Merge "Move LocalLifecycleOwner to common" into androidx-main
diff --git a/benchmark/benchmark-common/lint-baseline.xml b/benchmark/benchmark-common/lint-baseline.xml
index 96cf036..4dba6aa 100644
--- a/benchmark/benchmark-common/lint-baseline.xml
+++ b/benchmark/benchmark-common/lint-baseline.xml
@@ -1,77 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `stopAllPerfettoProcesses`"
- errorLine1=" PerfettoHelper.stopAllPerfettoProcesses()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 21 (current min is 19): `getPidsForProcess`"
- errorLine1=" fun getPerfettoPids() = Shell.getPidsForProcess(if (unbundled) "tracebox" else "perfetto")"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `PerfettoCapture`"
- errorLine1=" val capture = PerfettoCapture(unbundled)"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `start`"
- errorLine1=" capture.start("
- errorLine2=" ~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `isRunning`"
- errorLine1=" assertTrue(capture.isRunning())"
- errorLine2=" ~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `stopAllPerfettoProcesses`"
- errorLine1=" PerfettoHelper.stopAllPerfettoProcesses()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `isRunning`"
- errorLine1=" assertFalse(capture.isRunning())"
- errorLine2=" ~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 23 (current min is 19): `isAbiSupported`"
- errorLine1=" Assume.assumeTrue(PerfettoHelper.isAbiSupported())"
- errorLine2=" ~~~~~~~~~~~~~~">
- <location
- file="src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt"/>
- </issue>
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="UnsafeOptInUsageError"
diff --git a/benchmark/benchmark-macro/lint-baseline.xml b/benchmark/benchmark-macro/lint-baseline.xml
index 3743177..5309e22 100644
--- a/benchmark/benchmark-macro/lint-baseline.xml
+++ b/benchmark/benchmark-macro/lint-baseline.xml
@@ -1,23 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
-
- <issue
- id="NewApi"
- message="Class requires API level 29 (current min is 23): `Power`"
- errorLine1=" return if (type is PowerMetric.Type.Power) powerUw else energyUws"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/benchmark/macro/perfetto/PowerQuery.kt"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level 29 (current min is 23): `Power`"
- errorLine1=" return if (type is PowerMetric.Type.Power) powerUw else energyUws"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/benchmark/macro/perfetto/PowerQuery.kt"/>
- </issue>
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanThreadSleep"
diff --git a/buildSrc-tests/lint-baseline.xml b/buildSrc-tests/lint-baseline.xml
index 7bd6c6b..8f0a5db 100644
--- a/buildSrc-tests/lint-baseline.xml
+++ b/buildSrc-tests/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="EagerGradleConfiguration"
@@ -202,51 +202,6 @@
<issue
id="EagerGradleConfiguration"
message="Avoid using eager method findByName"
- errorLine1=" testExtension.sourceSets.findByName("main")?.let { sourceSet ->"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="${:buildSrc-tests*main*MAIN*sourceProvider*0*javaDir*4}/androidx/build/AndroidXImplPlugin.kt"/>
- </issue>
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
- errorLine1=" ?.findByName("main")"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="${:buildSrc-tests*main*MAIN*sourceProvider*0*javaDir*4}/androidx/build/AndroidXImplPlugin.kt"/>
- </issue>
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
- errorLine1=" ?.findByName("androidTest")"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="${:buildSrc-tests*main*MAIN*sourceProvider*0*javaDir*4}/androidx/build/AndroidXImplPlugin.kt"/>
- </issue>
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
- errorLine1=" ?.findByName("androidTest")"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="${:buildSrc-tests*main*MAIN*sourceProvider*0*javaDir*4}/androidx/build/AndroidXImplPlugin.kt"/>
- </issue>
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
- errorLine1=" target -> target.compilations.findByName("debugAndroidTest")"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="${:buildSrc-tests*main*MAIN*sourceProvider*0*javaDir*4}/androidx/build/AndroidXImplPlugin.kt"/>
- </issue>
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
errorLine1=" val androidConfiguration = project.configurations.findByName("implementation")"
errorLine2=" ~~~~~~~~~~">
<location
diff --git a/buildSrc/apply/applyAndroidXPaparazziImplPlugin.gradle b/buildSrc/apply/applyAndroidXPaparazziImplPlugin.gradle
deleted file mode 100644
index ece0f79..0000000
--- a/buildSrc/apply/applyAndroidXPaparazziImplPlugin.gradle
+++ /dev/null
@@ -1,9 +0,0 @@
-import androidx.build.paparazzi.AndroidXPaparazziImplPlugin
-
-buildscript {
- dependencies {
- classpath(project.files("${project.rootProject.ext["buildSrcOut"]}/private/build/libs/private.jar"))
- }
-}
-
-apply plugin: AndroidXPaparazziImplPlugin
diff --git a/buildSrc/plugins/src/main/kotlin/androidx/build/AndroidXPaparazziPlugin.kt b/buildSrc/plugins/src/main/kotlin/androidx/build/AndroidXPaparazziPlugin.kt
deleted file mode 100644
index 090d9b6..0000000
--- a/buildSrc/plugins/src/main/kotlin/androidx/build/AndroidXPaparazziPlugin.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build
-
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-
-/**
- * Configures screenshot testing using Paparazzi for AndroidX projects.
- *
- * The actual implementation is in AndroidXPaparazziImplPlugin.
- */
-class AndroidXPaparazziPlugin : Plugin<Project> {
- override fun apply(project: Project) {
- val supportRoot = project.getSupportRootFolder()
- project.apply(
- mapOf("from" to "$supportRoot/buildSrc/apply/applyAndroidXPaparazziImplPlugin.gradle")
- )
- }
-}
diff --git a/buildSrc/plugins/src/main/resources/META-INF/gradle-plugins/AndroidXPaparazziPlugin.properties b/buildSrc/plugins/src/main/resources/META-INF/gradle-plugins/AndroidXPaparazziPlugin.properties
deleted file mode 100644
index 872551c..0000000
--- a/buildSrc/plugins/src/main/resources/META-INF/gradle-plugins/AndroidXPaparazziPlugin.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright 2022 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.
-#
-
-implementation-class=androidx.build.AndroidXPaparazziPlugin
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
index 0c2315e..a67c3d3 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
@@ -733,7 +733,11 @@
private val hiddenAnnotationsJava: List<String> = emptyList()
// Annotations which mean the elements they are applied to should be hidden from the docs
-private val annotationsToHideApis: List<String> = listOf("androidx.annotation.RestrictTo")
+private val annotationsToHideApis: List<String> = listOf(
+ "androidx.annotation.RestrictTo",
+ // Appears in androidx.test sources
+ "dagger.internal.DaggerGenerated",
+)
/** Data class that matches JSON structure of kotlin source set metadata */
data class ProjectStructureMetadata(var sourceSets: List<SourceSetMetadata>)
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt
deleted file mode 100644
index 6c3b775..0000000
--- a/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build.paparazzi
-
-import androidx.build.OperatingSystem
-import androidx.build.defaultAndroidConfig
-import androidx.build.getLibraryByName
-import androidx.build.getOperatingSystem
-import androidx.build.getSdkPath
-import androidx.build.getSupportRootFolder
-import com.android.build.gradle.BaseExtension
-import javax.inject.Inject
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-import org.gradle.api.artifacts.type.ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE
-import org.gradle.api.artifacts.type.ArtifactTypeDefinition.JAR_TYPE
-import org.gradle.api.file.Directory
-import org.gradle.api.file.FileCollection
-import org.gradle.api.file.FileSystemOperations
-import org.gradle.api.provider.Provider
-import org.gradle.api.tasks.Copy
-import org.gradle.api.tasks.PathSensitivity
-import org.gradle.api.tasks.testing.Test
-import org.gradle.kotlin.dsl.get
-import org.gradle.kotlin.dsl.register
-import org.gradle.kotlin.dsl.the
-import org.gradle.kotlin.dsl.withType
-import org.gradle.process.JavaForkOptions
-
-/** Configures screenshot testing using Paparazzi for AndroidX projects. */
-class AndroidXPaparazziImplPlugin
-@Inject
-constructor(private val fileSystemOperations: FileSystemOperations) : Plugin<Project> {
- override fun apply(project: Project) {
- val paparazziNative = project.createUnzippedPaparazziNativeDependency()
- project.afterEvaluate { it.addTestUtilsDependency() }
- project.tasks.register("updateGolden")
- project.afterEvaluate {
- // need to be inside of afterEvaluate because we read android.namespace
- // ideally, we refactor to use a lazy API
- project.tasks.withType<Test>().configureEach { it.configureTestTask(paparazziNative) }
- }
- project.tasks.withType<Test>().whenTaskAdded { project.registerUpdateGoldenTask(it) }
- }
-
- /**
- * Add project's golden directory and the unzipped native Paparazzi location as task inputs, and
- * set system properties for the test library to consume at runtime.
- */
- private fun Test.configureTestTask(paparazziNative: FileCollection) {
- val compileSdkVersion = project.defaultAndroidConfig.compileSdk
- val platformDirectory = project.getSdkPath().resolve("platforms/$compileSdkVersion")
- val cachedGoldenRootDirectory = project.goldenRootDirectory
- val cachedReportDirectory = reportDirectory
- val android = project.the<BaseExtension>()
- val packageName =
- requireNotNull(android.namespace) { "android.namespace must be set for Paparazzi" }
-
- // Attach unzipped Paparazzi native directory as a task input
- inputs
- .files(paparazziNative)
- .withPathSensitivity(PathSensitivity.NONE)
- .withPropertyName("paparazziNative")
-
- // Attach golden directory to task inputs to invalidate tests when updating goldens
- inputs
- .dir(project.goldenDirectory)
- .withPathSensitivity(PathSensitivity.RELATIVE)
- .withPropertyName("goldenDirectory")
-
- // Mark report directory as an output directory
- outputs.dir(reportDirectory).withPropertyName("paparazziReportDir")
-
- // Clean the contents of the report directory before each test run
- doFirst {
- fileSystemOperations.delete {
- it.delete(cachedReportDirectory.get().asFile.listFiles())
- }
- }
-
- // Set non-path system properties at configuration time, so that changes invalidate caching
- prefixedSystemProperties(
- "gradlePluginApplied" to "true",
- "compileSdkVersion" to project.defaultAndroidConfig.targetSdk,
- "resourcePackageNames" to packageName, // TODO: Transitive resource packages?
- "modulePath" to project.modulePath,
- "updateGoldenTask" to "${project.path}:${updateGoldenTaskName()}"
- )
-
- // Set the remaining system properties at execution time, after the snapshotting, so that
- // the absolute paths don't affect caching
- doFirst {
- systemProperty("paparazzi.platform.data.root", paparazziNative.singleFile.canonicalPath)
- prefixedSystemProperties(
- "platformDir" to platformDirectory.canonicalPath,
- "assetsDir" to ".", // TODO: Merged assets dirs? (needed for compose?)
- "resDir" to ".", // TODO: Merged resource dirs? (needed for compose?)
- "reportDir" to cachedReportDirectory.get().asFile.canonicalPath,
- "goldenRootDir" to cachedGoldenRootDirectory.canonicalPath,
- )
- }
- }
-
- /** Register a copy task for moving new images to the golden directory. */
- private fun Project.registerUpdateGoldenTask(testTask: Test) {
- tasks.register<Copy>(testTask.updateGoldenTaskName()) {
- dependsOn(testTask)
-
- from(testTask.reportDirectory) {
- include("**/*_actual.png")
- into(goldenDirectory)
- rename { it.removeSuffix("_actual.png") + "_paparazzi.png" }
- }
- }
-
- tasks["updateGolden"].dependsOn(testTask.updateGoldenTaskName())
- }
-
- /** Derive updateGolden task name from a test task name. */
- private fun Test.updateGoldenTaskName(): String {
- return "updateGolden" + name.removePrefix("test").replaceFirstChar { it.titlecase() }
- }
-
- /**
- * Configure [UnzipPaparazziNativeTransform] for the project, and add the platform-specific
- * Paparazzi native layoutlib dependency, using the version in `libs.versions.toml`.
- */
- private fun Project.createUnzippedPaparazziNativeDependency(): FileCollection {
- val platformSuffix =
- when (val os = getOperatingSystem()) {
- OperatingSystem.LINUX -> "LinuxX64"
- OperatingSystem.MAC -> {
- val arch = System.getProperty("os.arch")
- if (arch.startsWith("x86", ignoreCase = true)) "MacOsX64" else "MacOsArm64"
- }
- else -> error("Unsupported operating system $os for Paparazzi")
- }
-
- dependencies.registerTransform(UnzipPaparazziNativeTransform::class.java) { spec ->
- spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_TYPE)
- spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, UNZIPPED_PAPARAZZI_NATIVE)
- }
-
- val configuration = configurations.create("paparazziNative")
- configuration.isCanBeConsumed = false
- configuration.dependencies.add(
- dependencies.create(getLibraryByName("paparazziNative$platformSuffix"))
- )
-
- return configuration.incoming
- .artifactView {
- it.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, UNZIPPED_PAPARAZZI_NATIVE)
- }
- .files
- }
-
- /** The golden image directory for this project. */
- private val Project.goldenDirectory
- get() = goldenRootDirectory.resolve(modulePath)
-
- /** The root of the golden image directory in a standard AndroidX checkout. */
- private val Project.goldenRootDirectory
- get() = getSupportRootFolder().resolve("../../golden")
-
- /** Filesystem path for this module derived from Gradle project path. */
- private val Project.modulePath
- get() = path.replace(':', '/').trim('/')
-
- /** Output directory for storing reports and images. */
- private val Test.reportDirectory: Provider<Directory>
- get() = project.layout.buildDirectory.dir("paparazzi/$name")
-
- /** Add a testImplementation dependency on the wrapper test utils library. */
- private fun Project.addTestUtilsDependency() {
- configurations["testImplementation"]
- .dependencies
- .add(dependencies.create(project(TEST_UTILS_PROJECT)))
- }
-
- private companion object {
- /** Package name of the test library, used to namespace system properties */
- const val PACKAGE_NAME = "androidx.testutils.paparazzi"
-
- /** Project path to the wrapper test utils project. */
- const val TEST_UTILS_PROJECT = ":internal-testutils-paparazzi"
-
- /** Artifact type attribute for unzipped Paparazzi layoutlib unzipped artifacts */
- const val UNZIPPED_PAPARAZZI_NATIVE = "unzipped-paparazzi-native"
-
- /** Set system properties with keys prefixed with [PACKAGE_NAME] */
- fun JavaForkOptions.prefixedSystemProperties(vararg properties: Pair<String, Any>) {
- properties.forEach { (name, value) -> systemProperty("$PACKAGE_NAME.$name", value) }
- }
- }
-}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/UnzipPaparazziNativeTransform.kt b/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/UnzipPaparazziNativeTransform.kt
deleted file mode 100644
index 2d2c09a..0000000
--- a/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/UnzipPaparazziNativeTransform.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build.paparazzi
-
-import java.util.zip.ZipInputStream
-import org.gradle.api.artifacts.transform.InputArtifact
-import org.gradle.api.artifacts.transform.TransformAction
-import org.gradle.api.artifacts.transform.TransformOutputs
-import org.gradle.api.artifacts.transform.TransformParameters.None
-import org.gradle.api.file.FileSystemLocation
-import org.gradle.api.provider.Provider
-import org.gradle.api.tasks.PathSensitive
-import org.gradle.api.tasks.PathSensitivity
-import org.gradle.work.DisableCachingByDefault
-
-/**
- * Unzips one of Paparazzi's platform-specific layoutlib JAR artifacts so that Paparazzi can read
- * its contents at run time. These contain a native dynamic library and supporting resources
- * including ICU and fonts.
- */
-@DisableCachingByDefault(because = "Just an unzip task, faster to rerun locally")
-abstract class UnzipPaparazziNativeTransform : TransformAction<None> {
- @get:PathSensitive(PathSensitivity.NAME_ONLY)
- @get:InputArtifact
- abstract val primaryInput: Provider<FileSystemLocation>
-
- override fun transform(outputs: TransformOutputs) {
- val inputFile = primaryInput.get().asFile
- val outputDir = outputs.dir(inputFile.nameWithoutExtension).also { it.mkdirs() }
-
- ZipInputStream(inputFile.inputStream().buffered()).use { zipInputStream ->
- while (true) {
- val entry = zipInputStream.nextEntry ?: break
- val outputFile = outputDir.resolve(entry.name)
-
- if (entry.isDirectory) {
- outputFile.mkdir()
- } else {
- // This works because ZipInputStream resizes itself to the contents of the
- // last-returned entry
- outputFile.outputStream().buffered().use { zipInputStream.copyTo(it) }
- }
- }
- }
- }
-}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/transform/ConfigureAarAsJar.kt b/buildSrc/private/src/main/kotlin/androidx/build/transform/ConfigureAarAsJar.kt
index b6c9910..877109a 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/transform/ConfigureAarAsJar.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/transform/ConfigureAarAsJar.kt
@@ -63,8 +63,6 @@
.dependencies
.add(project.dependencies.create(aarAsJar))
- // Added to allow the :external:paparazzi:paparazzi build to select the correct jar (not get
- // confused by the mpp jars) when the mpp builds are enabled
project.configurations
.getByName(testAarsAsJars.name)
.attributes
diff --git a/buildSrc/private/src/main/resources/META-INF/gradle-plugins/AndroidXPaparazziImplPlugin.properties b/buildSrc/private/src/main/resources/META-INF/gradle-plugins/AndroidXPaparazziImplPlugin.properties
deleted file mode 100644
index 0ea8b07..0000000
--- a/buildSrc/private/src/main/resources/META-INF/gradle-plugins/AndroidXPaparazziImplPlugin.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright 2022 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.
-#
-
-implementation-class=androidx.build.paparazzi.AndroidXPaparazziImplPlugin
diff --git a/buildSrc/settingsScripts/project-dependency-graph.groovy b/buildSrc/settingsScripts/project-dependency-graph.groovy
index d74e0d8..34e95d3 100644
--- a/buildSrc/settingsScripts/project-dependency-graph.groovy
+++ b/buildSrc/settingsScripts/project-dependency-graph.groovy
@@ -239,10 +239,6 @@
links.add(":compose:compiler:compiler")
links.add(":compose:lint:internal-lint-checks")
}
- if (paparazziPlugin.matcher(line).find()) {
- links.add(":test:screenshot:screenshot-proto")
- links.add(":internal-testutils-paparazzi")
- }
if (iconGenerator.matcher(line).find()) {
links.add(":compose:material:material:icons:generator")
}
@@ -267,7 +263,6 @@
private static Pattern multilineProjectReference = Pattern.compile("project\\(\$")
private static Pattern inspection = Pattern.compile("packageInspector\\(project, \"(.*)\"\\)")
private static Pattern composePlugin = Pattern.compile("id\\(\"AndroidXComposePlugin\"\\)")
- private static Pattern paparazziPlugin = Pattern.compile("id\\(\"AndroidXPaparazziPlugin\"\\)")
private static Pattern iconGenerator = Pattern.compile("IconGenerationTask\\.register")
}
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt
index 52325db..433564a 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraBackend.kt
@@ -86,6 +86,25 @@
return cameraController
}
+ override fun prewarm(cameraId: CameraId) {
+ _cameraControllers.find { it.cameraId == cameraId }?.simulateCameraStarted()
+ }
+
+ override fun disconnect(cameraId: CameraId) {
+ _cameraControllers.find { it.cameraId == cameraId }?.simulateCameraStopped()
+ }
+
+ override fun disconnectAsync(cameraId: CameraId): Deferred<Unit> {
+ _cameraControllers.find { it.cameraId == cameraId }?.simulateCameraStopped()
+ return CompletableDeferred(Unit)
+ }
+
+ override fun disconnectAll() {
+ _cameraControllers.forEach {
+ it.simulateCameraStopped()
+ }
+ }
+
companion object {
val FAKE_CAMERA_BACKEND_ID =
CameraBackendId("androidx.camera.camera2.pipe.testing.FakeCameraBackend")
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraDevices.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraDevices.kt
index 171f072..224a224 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraDevices.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeCameraDevices.kt
@@ -17,10 +17,12 @@
package androidx.camera.camera2.pipe.testing
import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraBackend
import androidx.camera.camera2.pipe.CameraBackendId
import androidx.camera.camera2.pipe.CameraDevices
import androidx.camera.camera2.pipe.CameraId
import androidx.camera.camera2.pipe.CameraMetadata
+import kotlinx.coroutines.Deferred
/**
* This provides a fake implementation of [CameraDevices] for tests with a fixed list of Cameras.
@@ -31,10 +33,16 @@
private val concurrentCameraBackendIds: Set<Set<CameraBackendId>>,
private val cameraMetadataMap: Map<CameraBackendId, List<CameraMetadata>>
) : CameraDevices {
+ private val cameraBackends: Map<CameraBackendId, CameraBackend>
+
init {
check(cameraMetadataMap.containsKey(defaultCameraBackendId)) {
"FakeCameraDevices must include $defaultCameraBackendId"
}
+
+ cameraBackends = cameraMetadataMap.mapValues { entry ->
+ FakeCameraBackend(entry.value.associateBy { it.camera })
+ }
}
override suspend fun getCameraIds(cameraBackendId: CameraBackendId?): List<CameraId>? =
@@ -51,8 +59,8 @@
override fun awaitConcurrentCameraIds(cameraBackendId: CameraBackendId?): Set<Set<CameraId>> {
return concurrentCameraBackendIds.map { concurrentCameraIds ->
- concurrentCameraIds.map {
- cameraId -> CameraId.fromCamera2Id(cameraId.value)
+ concurrentCameraIds.map { cameraId ->
+ CameraId.fromCamera2Id(cameraId.value)
}.toSet()
}.toSet()
}
@@ -70,6 +78,34 @@
return cameraMetadataMap[backendId]?.firstOrNull { it.camera == cameraId }
}
+ override fun prewarm(cameraId: CameraId, cameraBackendId: CameraBackendId?) {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ cameraBackend.prewarm(cameraId)
+ }
+
+ override fun disconnect(cameraId: CameraId, cameraBackendId: CameraBackendId?) {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ cameraBackend.disconnect(cameraId)
+ }
+
+ override fun disconnectAsync(
+ cameraId: CameraId,
+ cameraBackendId: CameraBackendId?
+ ): Deferred<Unit> {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ return cameraBackend.disconnectAsync(cameraId)
+ }
+
+ override fun disconnectAll(cameraBackendId: CameraBackendId?) {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ cameraBackend.disconnectAll()
+ }
+
+ override fun disconnectAllAsync(cameraBackendId: CameraBackendId?): Deferred<Unit> {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ return cameraBackend.disconnectAllAsync()
+ }
+
@Deprecated(
"findAll() is not able to specify a specific CameraBackendId to query.",
replaceWith = ReplaceWith("awaitCameraIds"),
@@ -99,4 +135,9 @@
)
override fun awaitMetadata(camera: CameraId): CameraMetadata =
checkNotNull(awaitCameraMetadata(camera))
+
+ private fun getCameraBackend(cameraBackendId: CameraBackendId?): CameraBackend {
+ val backendId = cameraBackendId ?: defaultCameraBackendId
+ return checkNotNull(cameraBackends[backendId]) { "Failed to load CameraBackend $backendId" }
+ }
}
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt
index 699f614..997ad8f 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraBackend.kt
@@ -128,6 +128,23 @@
graphListener: GraphListener,
streamGraph: StreamGraph
): CameraController
+
+ /** Connects and starts the underlying camera */
+ fun prewarm(cameraId: CameraId)
+
+ /** Disconnects the underlying camera.*/
+ fun disconnect(cameraId: CameraId)
+
+ /**
+ * Disconnects the underlying camera. Once the connection is closed, the returned [Deferred]
+ * should be completed.
+ */
+ fun disconnectAsync(cameraId: CameraId): Deferred<Unit>
+
+ /**
+ * Disconnects all active Cameras.
+ */
+ fun disconnectAll()
}
/**
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraDevices.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraDevices.kt
index 59c1012..76c367db 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraDevices.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraDevices.kt
@@ -21,6 +21,7 @@
import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
+import kotlinx.coroutines.Deferred
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
@@ -76,6 +77,39 @@
): CameraMetadata?
/**
+ * Opens the camera device indicated by the cameraId, so that any subsequent open calls will
+ * potentially have a better latency.
+ */
+ fun prewarm(cameraId: CameraId, cameraBackendId: CameraBackendId? = null)
+
+ /**
+ * Non blocking operation that disconnects the underlying active Camera.
+ */
+ fun disconnect(cameraId: CameraId, cameraBackendId: CameraBackendId? = null)
+
+ /**
+ * Disconnects the underlying active Camera. Once fully closed,
+ * the returned [Deferred] should be completed. It is synchronous with the other operations
+ * within this class.
+ */
+ fun disconnectAsync(
+ cameraId: CameraId,
+ cameraBackendId: CameraBackendId? = null
+ ): Deferred<Unit>
+
+ /**
+ * Non blocking operation that disconnects all active Cameras.
+ */
+ fun disconnectAll(cameraBackendId: CameraBackendId? = null)
+
+ /**
+ * Non blocking operation that disconnects all active Cameras. Once all connections are fully
+ * closed, the returned [Deferred] should be completed. It is synchronous with the other
+ * operations within this class.
+ */
+ fun disconnectAllAsync(cameraBackendId: CameraBackendId? = null): Deferred<Unit>
+
+ /**
* Iterate and return a list of CameraId's on the device that are capable of being opened. Some
* camera devices may be hidden or un-openable if they are included as part of a logical camera
* group.
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt
index 36d8450..34e1eaa 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2Backend.kt
@@ -39,8 +39,7 @@
/** This is the default [CameraBackend] implementation for CameraPipe based on Camera2. */
@RequiresApi(21)
internal class Camera2Backend
-@Inject
-constructor(
+@Inject constructor(
private val threads: Threads,
private val camera2DeviceCache: Camera2DeviceCache,
private val camera2MetadataCache: Camera2MetadataCache,
@@ -65,11 +64,26 @@
override fun awaitCameraMetadata(cameraId: CameraId): CameraMetadata =
camera2MetadataCache.awaitCameraMetadata(cameraId)
+ override fun disconnect(cameraId: CameraId) {
+ virtualCameraManager.close(cameraId)
+ }
+
+ override fun disconnectAsync(cameraId: CameraId): Deferred<Unit> {
+ TODO(
+ "b/324142928 - Add support in VirtualCameraManager for closing a camera " +
+ "with a deferred result."
+ )
+ }
+
+ override fun disconnectAll() {
+ return virtualCameraManager.closeAll()
+ }
+
override fun disconnectAllAsync(): Deferred<Unit> {
- // TODO: VirtualCameraManager needs to be extended to support a suspendable future that can
- // be used to wait until close has been called on all camera devices.
- virtualCameraManager.closeAll()
- return CompletableDeferred(Unit)
+ TODO(
+ "b/324142928 - Add support in VirtualCameraManager for closing a camera " +
+ "with a deferred result."
+ )
}
override fun shutdownAsync(): Deferred<Unit> {
@@ -86,16 +100,17 @@
streamGraph: StreamGraph
): CameraController {
// Use Dagger to create the camera2 controller component, then create the CameraController.
- val cameraControllerComponent =
- camera2CameraControllerComponent
- .camera2ControllerConfig(
- Camera2ControllerConfig(
- this, graphConfig, graphListener, streamGraph as StreamGraphImpl
- )
- )
- .build()
+ val cameraControllerComponent = camera2CameraControllerComponent.camera2ControllerConfig(
+ Camera2ControllerConfig(
+ this, graphConfig, graphListener, streamGraph as StreamGraphImpl
+ )
+ ).build()
// Create and return a Camera2 CameraController object.
return cameraControllerComponent.cameraController()
}
+
+ override fun prewarm(cameraId: CameraId) {
+ virtualCameraManager.prewarm(cameraId)
+ }
}
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
index 14dc332..8cf4b52 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCameraManager.kt
@@ -27,6 +27,7 @@
import androidx.camera.camera2.pipe.core.Threads
import androidx.camera.camera2.pipe.core.WakeLock
import androidx.camera.camera2.pipe.graph.GraphListener
+import androidx.camera.camera2.pipe.graph.GraphRequestProcessor
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineName
@@ -47,11 +48,29 @@
val isForegroundObserver: (Unit) -> Boolean,
) : CameraRequest()
+/**
+ * Sends a request to close an active camera.
+ * Note: RequestOpen() & RequestClose() may not be executed sequentially,
+ * as the camera may take a while to be fully opened, and RequestClose() might execute in parallel.
+ */
internal data class RequestClose(val activeCamera: VirtualCameraManager.ActiveCamera) :
CameraRequest()
+internal data class RequestCloseById(val activeCameraId: CameraId) :
+ CameraRequest()
+
internal object RequestCloseAll : CameraRequest()
+internal object NoOpGraphListener : GraphListener {
+ override fun onGraphStarted(requestProcessor: GraphRequestProcessor) {}
+
+ override fun onGraphStopped(requestProcessor: GraphRequestProcessor) {}
+
+ override fun onGraphModified(requestProcessor: GraphRequestProcessor) {}
+
+ override fun onGraphError(graphStateError: GraphState.GraphStateError) {}
+}
+
// A queue depth of 32 was deemed necessary in b/276051078 where a flood of requests can cause the
// queue depth to go over 8. In the long run, we can perhaps look into refactoring and
// reimplementing the request queue in a more robust way.
@@ -98,6 +117,16 @@
return result
}
+ /** Connects and starts the underlying camera.*/
+ internal fun prewarm(cameraId: CameraId) {
+ open(cameraId, emptyList(), NoOpGraphListener) { _ -> false }
+ }
+
+ /** Submits a request to close the underlying camera */
+ internal fun close(cameraId: CameraId) {
+ offerChecked(RequestCloseById(cameraId))
+ }
+
internal fun closeAll() {
if (!offerChecked(RequestCloseAll)) {
Log.warn { "Failed to close all cameras: Close request submission failed" }
@@ -133,6 +162,23 @@
continue
}
+ // Ensures the closure of a camera device happens after any preceding RequestOpen().
+ val closeRequestById = requests.firstOrNull()
+ if (closeRequestById != null && closeRequestById is RequestCloseById) {
+ requests.remove(closeRequestById)
+ pendingRequestOpens.removeAll {
+ it.virtualCamera.cameraId == closeRequestById.activeCameraId
+ }
+ val activeCamera =
+ activeCameras.firstOrNull { it.cameraId == closeRequestById.activeCameraId }
+ if (activeCamera != null) {
+ activeCameras.remove(activeCamera)
+ launch { activeCamera.close() }
+ activeCamera.awaitClosed()
+ }
+ continue
+ }
+
// If we received a closeAll request, then close every request leading up to it.
val closeAll = requests.indexOfLast { it is RequestCloseAll }
if (closeAll >= 0) {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt
index 0759f3e..2a143f3 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/config/ExternalCameraGraphComponent.kt
@@ -97,6 +97,22 @@
throwUnsupportedOperationException()
}
+ override fun prewarm(cameraId: CameraId) {
+ throwUnsupportedOperationException()
+ }
+
+ override fun disconnect(cameraId: CameraId) {
+ throwUnsupportedOperationException()
+ }
+
+ override fun disconnectAsync(cameraId: CameraId): Deferred<Unit> {
+ throwUnsupportedOperationException()
+ }
+
+ override fun disconnectAll() {
+ throwUnsupportedOperationException()
+ }
+
private fun throwUnsupportedOperationException(): Nothing =
throw UnsupportedOperationException("External CameraPipe should not use backends")
}
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/core/TokenLock.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/core/TokenLock.kt
index 4e035a2..3cfe9d85 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/core/TokenLock.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/core/TokenLock.kt
@@ -24,7 +24,6 @@
import androidx.camera.camera2.pipe.core.TokenLock.Token
import java.util.ArrayDeque
import kotlin.coroutines.resume
-import kotlin.coroutines.resumeWithException
import kotlin.math.min
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CancellableContinuation
@@ -87,17 +86,17 @@
}
/** Shorthand for "acquire(value, value)" */
-internal suspend inline fun TokenLock.acquire(value: Long): TokenLock.Token =
+internal suspend inline fun TokenLock.acquire(value: Long): Token =
this.acquire(value, value)
/** Shorthand for "acquireOrNull(value, value)" */
-internal inline fun TokenLock.acquireOrNull(value: Long): TokenLock.Token? =
+internal inline fun TokenLock.acquireOrNull(value: Long): Token? =
this.acquireOrNull(value, value)
/** Executes the given action while holding a token. */
internal suspend inline fun <T> TokenLock.withToken(
value: Long,
- crossinline action: (token: TokenLock.Token) -> T
+ crossinline action: (token: Token) -> T
): T {
this.acquire(value).use {
return action(it)
@@ -108,7 +107,7 @@
internal suspend inline fun <T> TokenLock.withToken(
min: Long,
max: Long,
- crossinline action: (token: TokenLock.Token) -> T
+ crossinline action: (token: Token) -> T
): T {
this.acquire(min, max).use {
return action(it)
@@ -116,10 +115,6 @@
}
internal class TokenLockImpl(override val capacity: Long) : TokenLock {
- companion object {
- val closedException = CancellationException()
- }
-
private val pending = ArrayDeque<TokenRequest>()
@GuardedBy("pending")
@@ -148,8 +143,8 @@
}
}
- override fun acquireOrNull(min: Long, max: Long): TokenLock.Token? {
- if (min > capacity) throw IllegalArgumentException("Attempted to acquire $min / $capacity")
+ override fun acquireOrNull(min: Long, max: Long): Token? {
+ require(min <= capacity) { "Cannot acquire more than $capacity (requested $min)" }
synchronized(pending) {
if (closed) return null
@@ -165,17 +160,14 @@
return null
}
- override suspend fun acquire(min: Long, max: Long): TokenLock.Token =
+ override suspend fun acquire(min: Long, max: Long): Token =
suspendCancellableCoroutine { continuation ->
- if (min > capacity) {
- continuation.resumeWithException(
- IllegalArgumentException("Attempted to acquire $min / $capacity")
- )
- return@suspendCancellableCoroutine
- }
-
+ require(min <= capacity) { "Cannot acquire more than $capacity (requested $min)" }
synchronized(pending) {
- if (closed) throw closedException
+ if (closed) {
+ continuation.cancel()
+ return@suspendCancellableCoroutine
+ }
if (pending.isEmpty()) {
val value = min(_available, max)
if (value >= min) {
@@ -248,7 +240,7 @@
}
// If we fulfilled 1 or more requests, then create and pass tokens to the
- // continuation outside of the syncronized block.
+ // continuation outside of the synchronized block.
if (requests.isNotEmpty()) {
requestsToComplete = requests
}
@@ -259,13 +251,13 @@
}
private class TokenRequest(
- val continuation: CancellableContinuation<TokenLock.Token>,
+ val continuation: CancellableContinuation<Token>,
val min: Long,
val max: Long,
var token: TokenImpl? = null
)
- inner class TokenImpl(override val value: Long) : TokenLock.Token {
+ inner class TokenImpl(override val value: Long) : Token {
private val closed = atomic(false)
override fun close() {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraDevicesImpl.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraDevicesImpl.kt
index 6f0b2bd..d2798d62 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraDevicesImpl.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/CameraDevicesImpl.kt
@@ -27,6 +27,7 @@
import androidx.camera.camera2.pipe.core.Log
import javax.inject.Inject
import javax.inject.Singleton
+import kotlinx.coroutines.Deferred
/** Provides utilities for querying cameras and accessing metadata about those cameras. */
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
@@ -118,6 +119,34 @@
return metadata
}
+ override fun prewarm(cameraId: CameraId, cameraBackendId: CameraBackendId?) {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ cameraBackend.prewarm(cameraId)
+ }
+
+ override fun disconnect(cameraId: CameraId, cameraBackendId: CameraBackendId?) {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ cameraBackend.disconnect(cameraId)
+ }
+
+ override fun disconnectAsync(
+ cameraId: CameraId,
+ cameraBackendId: CameraBackendId?
+ ): Deferred<Unit> {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ return cameraBackend.disconnectAsync(cameraId)
+ }
+
+ override fun disconnectAll(cameraBackendId: CameraBackendId?) {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ cameraBackend.disconnectAll()
+ }
+
+ override fun disconnectAllAsync(cameraBackendId: CameraBackendId?): Deferred<Unit> {
+ val cameraBackend = getCameraBackend(cameraBackendId)
+ return cameraBackend.disconnectAllAsync()
+ }
+
private fun getCameraBackend(cameraBackendId: CameraBackendId?): CameraBackend =
Debug.trace("getCameraBackend") {
val actualBackendId = cameraBackendId ?: cameraBackends.default.id
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/OutputDistributor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/OutputDistributor.kt
index 91c4338..4d24319 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/OutputDistributor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/internal/OutputDistributor.kt
@@ -148,14 +148,9 @@
val isOutOfOrder = isFrameNumberOutOfOrder || isOutputNumberOutOfOrder
// onOutputStarted should only be invoked once. Check to see that there are no other
- // duplicate events.
- check(
- !startedOutputs.any {
- it.cameraFrameNumber == cameraFrameNumber ||
- it.cameraTimestamp == cameraTimestamp ||
- it.outputNumber == outputNumber
- }
- ) {
+ // duplicate events. Note that on some platforms, non-compliant camera HALs may return
+ // frames with identical frame numbers and output numbers. See b/324320062 for context.
+ check(!startedOutputs.any { it.cameraFrameNumber == cameraFrameNumber }) {
"onOutputStarted was invoked multiple times with a previously started output!" +
"onOutputStarted with $cameraFrameNumber, $cameraTimestamp, $outputNumber. " +
"Previously started outputs: $startedOutputs"
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/internal/OutputDistributorTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/internal/OutputDistributorTest.kt
index 42bf6cc..3386f26 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/internal/OutputDistributorTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/internal/OutputDistributorTest.kt
@@ -22,7 +22,10 @@
import androidx.camera.camera2.pipe.OutputStatus
import androidx.camera.camera2.pipe.internal.OutputDistributor.OutputListener
import androidx.camera.camera2.pipe.media.Finalizer
+import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
+import junit.framework.TestCase.assertFalse
+import junit.framework.TestCase.assertTrue
import kotlinx.atomicfu.atomic
import org.junit.Test
import org.junit.runner.RunWith
@@ -447,6 +450,57 @@
assertThat(pendingOutput1.outputStatus).isEqualTo(OutputStatus.ERROR_OUTPUT_FAILED)
}
+ @Test
+ fun outputDistributorThrowsOnIdenticalFrameNumber() {
+ val pendingOutput1 =
+ PendingOutput(FrameNumber(1), CameraTimestamp(11), outputNumber = 101)
+ val pendingOutput2 =
+ PendingOutput(FrameNumber(1), CameraTimestamp(12), outputNumber = 102)
+ outputDistributor.startWith(pendingOutput1)
+
+ assertThrows<IllegalStateException> {
+ outputDistributor.startWith(pendingOutput2)
+ }
+ }
+
+ @Test
+ fun pendingOutputCompletesOnIdenticalTimestamps() {
+ val pendingOutput1 =
+ PendingOutput(FrameNumber(1), CameraTimestamp(11), outputNumber = 101)
+ val pendingOutput2 =
+ PendingOutput(FrameNumber(2), CameraTimestamp(11), outputNumber = 102)
+ outputDistributor.startWith(pendingOutput1)
+ outputDistributor.startWith(pendingOutput2)
+
+ outputDistributor.onOutputResult(fakeOutput1.outputNumber, OutputResult.from(fakeOutput1))
+ assertTrue(pendingOutput1.isComplete)
+ assertFalse(pendingOutput2.isComplete)
+
+ outputDistributor.onOutputResult(fakeOutput2.outputNumber, OutputResult.from(fakeOutput2))
+ assertTrue(pendingOutput1.isComplete)
+ assertTrue(pendingOutput2.isComplete)
+ }
+
+ @Test
+ fun pendingOutputCompletesOnIdenticalOutputNumbers() {
+ val pendingOutput1 =
+ PendingOutput(FrameNumber(1), CameraTimestamp(11), outputNumber = 101)
+ val pendingOutput2 =
+ PendingOutput(FrameNumber(2), CameraTimestamp(12), outputNumber = 101)
+ outputDistributor.startWith(pendingOutput1)
+ outputDistributor.startWith(pendingOutput2)
+
+ val fakeOutput1 = FakeOutput(101)
+ outputDistributor.onOutputResult(fakeOutput1.outputNumber, OutputResult.from(fakeOutput1))
+ assertTrue(pendingOutput1.isComplete)
+ assertFalse(pendingOutput2.isComplete)
+
+ val fakeOutput2 = FakeOutput(101)
+ outputDistributor.onOutputResult(fakeOutput2.outputNumber, OutputResult.from(fakeOutput2))
+ assertTrue(pendingOutput1.isComplete)
+ assertTrue(pendingOutput2.isComplete)
+ }
+
/**
* Utility class that implements [OutputListener] and can be used to observe when an
* output is complete and the callback is invoked.
diff --git a/camera/integration-tests/uiwidgetstestapp/build.gradle b/camera/integration-tests/uiwidgetstestapp/build.gradle
index 98a7d6a..1e7bafb5 100644
--- a/camera/integration-tests/uiwidgetstestapp/build.gradle
+++ b/camera/integration-tests/uiwidgetstestapp/build.gradle
@@ -60,7 +60,6 @@
}
dependencies {
-
// Internal library
implementation(libs.kotlinStdlib)
implementation(project(":camera:camera-core"))
@@ -70,7 +69,7 @@
implementation(project(":camera:camera-view"))
implementation(project(":camera:camera-video"))
implementation(project(":camera:camera-mlkit-vision"))
- implementation 'com.google.mlkit:barcode-scanning:17.0.2'
+ implementation("com.google.mlkit:barcode-scanning:17.0.2")
// Android Support Library
implementation("androidx.appcompat:appcompat:1.2.0")
@@ -88,15 +87,14 @@
implementation(libs.guavaAndroid)
// Compose
- implementation 'androidx.activity:activity-compose:1.4.0'
- implementation project(':compose:material:material')
- implementation 'androidx.compose.animation:animation:1.4.0'
- implementation 'androidx.compose.runtime:runtime:1.4.0'
- implementation 'androidx.compose.ui:ui-tooling:1.4.0'
- implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1'
- implementation 'androidx.navigation:navigation-compose:2.4.2'
- implementation 'androidx.compose.material:material-icons-extended:1.4.0'
- androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.1.1'
+ implementation("androidx.activity:activity-compose:1.4.0")
+ implementation(project(":compose:material:material"))
+ implementation("androidx.compose.animation:animation:1.4.0")
+ implementation("androidx.compose.runtime:runtime:1.4.0")
+ implementation("androidx.compose.ui:ui-tooling:1.4.0")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.4.1")
+ implementation("androidx.navigation:navigation-compose:2.4.2")
+ implementation("androidx.compose.material:material-icons-extended:1.4.0")
// Align dependencies in debugRuntimeClasspath and debugAndroidTestRuntimeClasspath.
androidTestImplementation("androidx.annotation:annotation-experimental:1.4.0")
@@ -125,16 +123,14 @@
// Testing for Compose
// Test rules and transitive dependencies:
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(project(":compose:runtime:runtime"))
androidTestImplementation(project(":compose:ui:ui"))
- androidTestImplementation(project(":compose:runtime:runtime-saveable"))
androidTestImplementation(project(":compose:ui:ui-geometry"))
androidTestImplementation(project(":compose:ui:ui-util"))
androidTestImplementation(project(":compose:ui:ui-graphics"))
androidTestImplementation(project(":compose:ui:ui-unit"))
androidTestImplementation(project(":compose:ui:ui-text"))
+ androidTestImplementation(project(":compose:ui:ui-test-junit4"))
androidTestImplementation("androidx.collection:collection:1.4.0")
// Needed for createComposeRule, but not createAndroidComposeRule:
- debugImplementation(project(":compose:ui:ui-test-manifest"))
+ debugImplementation("androidx.compose.ui:ui-test-manifest:1.6.0")
}
diff --git a/cardview/cardview/lint-baseline.xml b/cardview/cardview/lint-baseline.xml
deleted file mode 100644
index cc40871..0000000
--- a/cardview/cardview/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-alpha10" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-alpha10)" variant="all" version="8.3.0-alpha10">
-
- <issue
- id="NewApi"
- message="Class requires API level 21 (current min is 19): `CardViewApi21Impl`"
- errorLine1=" if (!(IMPL instanceof CardViewApi21Impl)) {"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/cardview/widget/CardView.java"/>
- </issue>
-
-</issues>
diff --git a/collection/collection/api/current.txt b/collection/collection/api/current.txt
index 387bef3..9c394df 100644
--- a/collection/collection/api/current.txt
+++ b/collection/collection/api/current.txt
@@ -34,7 +34,7 @@
method public boolean addAll(java.util.Collection<? extends E> elements);
method public void clear();
method public operator boolean contains(E element);
- method public boolean containsAll(java.util.Collection<E> elements);
+ method public boolean containsAll(java.util.Collection<? extends E> elements);
method public void ensureCapacity(int minimumCapacity);
method public int getSize();
method public int indexOf(Object? key);
@@ -42,9 +42,9 @@
method public java.util.Iterator<E> iterator();
method public boolean remove(E element);
method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
- method public boolean removeAll(java.util.Collection<E> elements);
+ method public boolean removeAll(java.util.Collection<? extends E> elements);
method public E removeAt(int index);
- method public boolean retainAll(java.util.Collection<E> elements);
+ method public boolean retainAll(java.util.Collection<? extends E> elements);
method public Object?[] toArray();
method public <T> T[] toArray(T[] array);
method public E valueAt(int index);
diff --git a/collection/collection/api/restricted_current.txt b/collection/collection/api/restricted_current.txt
index 8b4f85d..042ced8 100644
--- a/collection/collection/api/restricted_current.txt
+++ b/collection/collection/api/restricted_current.txt
@@ -34,7 +34,7 @@
method public boolean addAll(java.util.Collection<? extends E> elements);
method public void clear();
method public operator boolean contains(E element);
- method public boolean containsAll(java.util.Collection<E> elements);
+ method public boolean containsAll(java.util.Collection<? extends E> elements);
method public void ensureCapacity(int minimumCapacity);
method public int getSize();
method public int indexOf(Object? key);
@@ -42,9 +42,9 @@
method public java.util.Iterator<E> iterator();
method public boolean remove(E element);
method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
- method public boolean removeAll(java.util.Collection<E> elements);
+ method public boolean removeAll(java.util.Collection<? extends E> elements);
method public E removeAt(int index);
- method public boolean retainAll(java.util.Collection<E> elements);
+ method public boolean retainAll(java.util.Collection<? extends E> elements);
method public Object?[] toArray();
method public <T> T[] toArray(T[] array);
method public E valueAt(int index);
diff --git a/compose/animation/animation-core/build.gradle b/compose/animation/animation-core/build.gradle
index c175361..fbc84ec 100644
--- a/compose/animation/animation-core/build.gradle
+++ b/compose/animation/animation-core/build.gradle
@@ -40,9 +40,10 @@
sourceSets {
commonMain {
dependencies {
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:ui:ui"))
- implementation(project(":compose:ui:ui-unit"))
+ implementation("androidx.compose.runtime:runtime:1.6.0")
+ implementation("androidx.compose.ui:ui:1.6.0")
+ implementation("androidx.compose.ui:ui-unit:1.6.0")
+ implementation(project(":compose:ui:ui-graphics"))
implementation(project(":compose:ui:ui-util"))
implementation("androidx.collection:collection:1.4.0")
implementation(libs.kotlinStdlibCommon)
@@ -75,11 +76,6 @@
desktopMain {
dependsOn(jvmMain)
dependencies {
- implementation(libs.kotlinStdlib)
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:ui:ui"))
- implementation(project(":compose:ui:ui-unit"))
- implementation(project(":compose:ui:ui-util"))
}
}
diff --git a/compose/animation/animation-core/lint-baseline.xml b/compose/animation/animation-core/lint-baseline.xml
index f95935a..9b328d7 100644
--- a/compose/animation/animation-core/lint-baseline.xml
+++ b/compose/animation/animation-core/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanSuppressTag"
@@ -76,17 +76,8 @@
<issue
id="PrimitiveInCollection"
message="constructor VectorizedKeyframesSpec has parameter keyframes with type Map<Integer, ? extends Pair<? extends V, ? extends Easing>>: replace with IntObjectMap"
- errorLine1=" private val keyframes: Map<Int, Pair<V, Easing>>,"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/commonMain/kotlin/androidx/compose/animation/core/VectorizedAnimationSpec.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field keyframes with type Map<Integer, Pair<V, Easing>>: replace with IntObjectMap"
- errorLine1=" private val keyframes: Map<Int, Pair<V, Easing>>,"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ errorLine1=" keyframes: Map<Int, Pair<V, Easing>>,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/commonMain/kotlin/androidx/compose/animation/core/VectorizedAnimationSpec.kt"/>
</issue>
diff --git a/compose/animation/animation-core/samples/build.gradle b/compose/animation/animation-core/samples/build.gradle
index dc3cfcbd..f566a97 100644
--- a/compose/animation/animation-core/samples/build.gradle
+++ b/compose/animation/animation-core/samples/build.gradle
@@ -36,7 +36,7 @@
implementation(project(":compose:animation:animation"))
implementation(project(":compose:animation:animation-core"))
implementation(project(":compose:runtime:runtime"))
- implementation("androidx.compose.ui:ui:1.2.1")
+ implementation(project(":compose:ui:ui"))
implementation("androidx.compose.ui:ui-unit:1.2.1")
implementation("androidx.compose.foundation:foundation:1.2.1")
implementation("androidx.compose.foundation:foundation-layout:1.2.1")
diff --git a/compose/animation/animation-graphics/build.gradle b/compose/animation/animation-graphics/build.gradle
index 582509b..150d58b 100644
--- a/compose/animation/animation-graphics/build.gradle
+++ b/compose/animation/animation-graphics/build.gradle
@@ -42,13 +42,12 @@
implementation(libs.kotlinStdlibCommon)
api(project(":compose:animation:animation"))
- api(project(":compose:foundation:foundation-layout"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-geometry"))
+ api("androidx.compose.foundation:foundation-layout:1.6.0")
+ api("androidx.compose.runtime:runtime:1.6.0")
+ api("androidx.compose.ui:ui:1.6.0")
+ api("androidx.compose.ui:ui-geometry:1.6.0")
implementation(project(":compose:ui:ui-util"))
-
implementation("androidx.collection:collection:1.4.0")
}
}
@@ -69,7 +68,6 @@
}
}
-
androidMain {
dependsOn(jvmMain)
dependencies {
@@ -80,11 +78,6 @@
dependsOn(jvmMain)
dependencies {
implementation(libs.kotlinStdlib)
- api(project(":compose:foundation:foundation-layout"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-geometry"))
- implementation(project(":compose:ui:ui-util"))
}
}
diff --git a/compose/animation/animation/build.gradle b/compose/animation/animation/build.gradle
index 6a28b1d..f8204bf 100644
--- a/compose/animation/animation/build.gradle
+++ b/compose/animation/animation/build.gradle
@@ -42,10 +42,10 @@
implementation(libs.kotlinStdlibCommon)
api(project(":compose:animation:animation-core"))
- api(project(":compose:foundation:foundation-layout"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-geometry"))
+ api("androidx.compose.foundation:foundation-layout:1.6.0")
+ api("androidx.compose.runtime:runtime:1.6.0")
+ api("androidx.compose.ui:ui:1.6.0")
+ api("androidx.compose.ui:ui-geometry:1.6.0")
implementation(project(":compose:ui:ui-util"))
@@ -77,13 +77,6 @@
dependsOn(jvmMain)
dependencies {
implementation(libs.kotlinStdlib)
-
- api(project(":compose:foundation:foundation-layout"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-geometry"))
-
- implementation(project(":compose:ui:ui-util"))
}
}
diff --git a/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml b/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml
index b3839ca..c1d1294 100644
--- a/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml
+++ b/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="PrimitiveInCollection"
@@ -39,24 +39,6 @@
<issue
id="PrimitiveInCollection"
- message="variable sizeMap with type Map<T, IntSize>: replace with ObjectLongMap"
- errorLine1=" val sizeMap = remember { mutableMapOf<T, IntSize>() }"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/animation/demos/lookahead/CraneDemo.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable offsetMap with type Map<T, Offset>: replace with ObjectLongMap"
- errorLine1=" val offsetMap = remember { mutableMapOf<T, Offset>() }"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/animation/demos/lookahead/CraneDemo.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
message="field colors with type List<Color>: replace with LongList"
errorLine1="private val colors = listOf("
errorLine2="^">
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
index 7e19a0f..3ba1cac 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/jvmTest/kotlin/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
@@ -123,7 +123,8 @@
// replace source keys for start group calls
.replace(
Regex(
- "(%composer\\.start(Restart|Movable|Replaceable)Group\\()-?((0b)?[-\\d]+)"
+ "(%composer\\.start(Restart|Movable|Replaceable|Replace)" +
+ "Group\\()-?((0b)?[-\\d]+)"
)
) {
val stringKey = it.groupValues[3]
@@ -162,7 +163,7 @@
// replace source information with source it references
.replace(
Regex(
- "(%composer\\.start(Restart|Movable|Replaceable)Group\\" +
+ "(%composer\\.start(Restart|Movable|Replaceable|Replace)Group\\" +
"([^\"\\n]*)\"(.*)\"\\)"
)
) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = false\135.txt"
index a1a28e8..07aa131 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = false\135.txt"
@@ -26,7 +26,7 @@
object : C {
@Composable
override fun Render(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Render)<B()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -48,7 +48,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = true\135.txt"
index a1a28e8..07aa131 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/composableLocalFunctionInsideLocalClass\133useFir = true\135.txt"
@@ -26,7 +26,7 @@
object : C {
@Composable
override fun Render(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Render)<B()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -48,7 +48,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = false\135.txt"
index c95de31..3975f63 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = false\135.txt"
@@ -41,7 +41,7 @@
@NonRestartableComposable
@Composable
override fun bar(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(bar):Test.kt#2487m")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -49,7 +49,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
static val %stable: Int = 0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = true\135.txt"
index c95de31..3975f63 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ComposerParamTransformTests/testAbstractComposable\133useFir = true\135.txt"
@@ -41,7 +41,7 @@
@NonRestartableComposable
@Composable
override fun bar(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(bar):Test.kt#2487m")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -49,7 +49,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
static val %stable: Int = 0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt"
index 65f9106..a65bb12 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = false\135.txt"
@@ -33,12 +33,12 @@
}
with(foo) {
A(%this%with, %composer, 0)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>")
with(Bar()) {
B(%this%with, %this%with, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt"
index 65f9106..a65bb12 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ContextReceiversTransformTests/testContextReceiversNestedWith\133useFir = true\135.txt"
@@ -33,12 +33,12 @@
}
with(foo) {
A(%this%with, %composer, 0)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>")
with(Bar()) {
B(%this%with, %this%with, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = false\135.txt"
index f051992..87b3736 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = false\135.txt"
@@ -25,10 +25,10 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>,<B()>")
val tmp0_group = B(%composer, 0) && B(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = true\135.txt"
index f051992..87b3736 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testAND\133useFir = true\135.txt"
@@ -25,10 +25,10 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>,<B()>")
val tmp0_group = B(%composer, 0) && B(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = false\135.txt"
index d400019..b3459ca 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = false\135.txt"
@@ -30,7 +30,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
while (items.hasNext()) {
val i = items.next()
@@ -39,7 +39,7 @@
}
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = true\135.txt"
index d400019..b3459ca 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsAfter\133useFir = true\135.txt"
@@ -30,7 +30,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
while (items.hasNext()) {
val i = items.next()
@@ -39,7 +39,7 @@
}
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = false\135.txt"
index 0945fc9..2547f95 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = false\135.txt"
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>,<P(i)>")
while (items.hasNext()) {
val i = items.next()
@@ -43,7 +43,7 @@
}
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = true\135.txt"
index 0945fc9..2547f95 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfterAndCallAfter\133useFir = true\135.txt"
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>,<P(i)>")
while (items.hasNext()) {
val i = items.next()
@@ -43,7 +43,7 @@
}
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = false\135.txt"
index bc9a8a3..3b2d8d9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = false\135.txt"
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>,<P(j)>")
while (items.hasNext()) {
val i = items.next()
@@ -44,7 +44,7 @@
}
P(j, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = true\135.txt"
index bc9a8a3..3b2d8d9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBeforeAndAfter\133useFir = true\135.txt"
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>,<P(j)>")
while (items.hasNext()) {
val i = items.next()
@@ -44,7 +44,7 @@
}
P(j, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = false\135.txt"
index 3efd13f..b2d254e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = false\135.txt"
@@ -30,7 +30,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
while (items.hasNext()) {
val i = items.next()
@@ -39,7 +39,7 @@
break
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = true\135.txt"
index 3efd13f..b2d254e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testBreakWithCallsBefore\133useFir = true\135.txt"
@@ -30,7 +30,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
while (items.hasNext()) {
val i = items.next()
@@ -39,7 +39,7 @@
break
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt"
index 99f3e5e..aee5bdf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = false\135.txt"
@@ -24,7 +24,7 @@
val property: A
@Composable @JvmName(name = "getProperty")
get() {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
@Composable
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt"
index 99f3e5e..aee5bdf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testComposableInAnonymousObjectDelegate\133useFir = true\135.txt"
@@ -24,7 +24,7 @@
val property: A
@Composable @JvmName(name = "getProperty")
get() {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
@Composable
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = false\135.txt"
index aca099e..7f0f74b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = false\135.txt"
@@ -30,20 +30,20 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(i)>")
val i = items.next()
if (i == 0) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
P(i, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = true\135.txt"
index aca099e..7f0f74b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsAfter\133useFir = true\135.txt"
@@ -30,20 +30,20 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(i)>")
val i = items.next()
if (i == 0) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
P(i, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = false\135.txt"
index ee4b2ed..a679ce7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = false\135.txt"
@@ -31,21 +31,21 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(i)>,<P(i)>")
val i = items.next()
P(i, %composer, 0)
if (i == 0) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
P(i, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = true\135.txt"
index ee4b2ed..a679ce7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBeforeAndAfter\133useFir = true\135.txt"
@@ -31,21 +31,21 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(i)>,<P(i)>")
val i = items.next()
P(i, %composer, 0)
if (i == 0) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
P(i, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = false\135.txt"
index 867c78d..2525fd7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = false\135.txt"
@@ -31,21 +31,21 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(i)>")
val i = items.next()
P(i, %composer, 0)
if (i == 0) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
print(i)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = true\135.txt"
index 867c78d..2525fd7 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testContinueWithCallsBefore\133useFir = true\135.txt"
@@ -31,21 +31,21 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(i)>")
val i = items.next()
P(i, %composer, 0)
if (i == 0) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
print(i)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = false\135.txt"
index 335a543..8f91499 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = false\135.txt"
@@ -29,23 +29,23 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0 = <block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
val tmp4_group = if (x > 0) {
- val tmp3_group = if (%composer.startReplaceableGroup(<>)
+ val tmp3_group = if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>")
val tmp1_group = B(%composer, 0)
- %composer.endReplaceableGroup()
- tmp1_group) 1 else if (%composer.startReplaceableGroup(<>)
+ %composer.endReplaceGroup()
+ tmp1_group) 1 else if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>")
val tmp2_group = B(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group) 2 else 3
tmp3_group
} else {
4
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp4_group
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = true\135.txt"
index 335a543..8f91499 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testDynamicWrappingGroupWithReturnValue\133useFir = true\135.txt"
@@ -29,23 +29,23 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0 = <block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
val tmp4_group = if (x > 0) {
- val tmp3_group = if (%composer.startReplaceableGroup(<>)
+ val tmp3_group = if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>")
val tmp1_group = B(%composer, 0)
- %composer.endReplaceableGroup()
- tmp1_group) 1 else if (%composer.startReplaceableGroup(<>)
+ %composer.endReplaceGroup()
+ tmp1_group) 1 else if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>")
val tmp2_group = B(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group) 2 else 3
tmp3_group
} else {
4
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp4_group
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = false\135.txt"
index a8106b9..78cdf3e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = false\135.txt"
@@ -23,27 +23,27 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<R()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R()>")
if (x > 0) {
val tmp1_return = R(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val tmp0 = R(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = true\135.txt"
index a8106b9..78cdf3e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnCallValue\133useFir = true\135.txt"
@@ -23,27 +23,27 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<R()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R()>")
if (x > 0) {
val tmp1_return = R(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val tmp0 = R(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt"
index 6eb97a7..9874dcf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = false\135.txt"
@@ -29,12 +29,12 @@
}
Dialog({ %composer: Composer?, %changed: Int ->
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Test(p...>")
if (false) {
Test(param, %composer, 0b1110 and %dirty)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt"
index 6eb97a7..9874dcf 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromCrossInlinedLambda\133useFir = true\135.txt"
@@ -29,12 +29,12 @@
}
Dialog({ %composer: Composer?, %changed: Int ->
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Test(p...>")
if (false) {
Test(param, %composer, 0b1110 and %dirty)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = false\135.txt"
index af9595d..2711f11 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = false\135.txt"
@@ -38,10 +38,10 @@
val tmp0_subject = state.value
when {
tmp0_subject == true -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Text(t...>")
val tmp1_return = Text("true", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
@@ -51,10 +51,10 @@
return tmp1_return
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Text(t...>")
Text("false", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = true\135.txt"
index af9595d..2711f11 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnFromWhenStatement\133useFir = true\135.txt"
@@ -38,10 +38,10 @@
val tmp0_subject = state.value
when {
tmp0_subject == true -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Text(t...>")
val tmp1_return = Text("true", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
@@ -51,10 +51,10 @@
return tmp1_return
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Text(t...>")
Text("false", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = false\135.txt"
index 6d045c2..3466566 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = false\135.txt"
@@ -24,7 +24,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -34,7 +34,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
A(%composer, 0)
@@ -42,6 +42,6 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = true\135.txt"
index 6d045c2..3466566 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValueWithCallsAfter\133useFir = true\135.txt"
@@ -24,7 +24,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -34,7 +34,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
A(%composer, 0)
@@ -42,6 +42,6 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = false\135.txt"
index 904ae2a..06474c2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = false\135.txt"
@@ -24,7 +24,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -35,13 +35,13 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
val tmp0 = 2
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = true\135.txt"
index 904ae2a..06474c2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnValue\133useFir = true\135.txt"
@@ -24,7 +24,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -35,13 +35,13 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
val tmp0 = 2
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = false\135.txt"
index 66cec40..aa2146c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = false\135.txt"
@@ -24,7 +24,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -33,12 +33,12 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = true\135.txt"
index 66cec40..aa2146c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsAfterButNotBefore\133useFir = true\135.txt"
@@ -24,7 +24,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -33,12 +33,12 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = false\135.txt"
index e698b4b..4d0b5f4 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = false\135.txt"
@@ -25,7 +25,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -35,12 +35,12 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
print("hello")
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = true\135.txt"
index e698b4b..4d0b5f4 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEarlyReturnWithCallsBeforeButNotAfter\133useFir = true\135.txt"
@@ -25,7 +25,7 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -35,12 +35,12 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
print("hello")
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = false\135.txt"
index 6b3b281..da5c0d3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
}
val y = <block>{
val <elvis> = x
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R()>")
val tmp0_group = when {
<elvis> == null -> {
@@ -39,7 +39,7 @@
<elvis>
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = true\135.txt"
index 6b3b281..da5c0d3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testElvis\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
}
val y = <block>{
val <elvis> = x
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R()>")
val tmp0_group = when {
<elvis> == null -> {
@@ -39,7 +39,7 @@
<elvis>
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt"
index abf76e6..33fa453 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = false\135.txt"
@@ -33,14 +33,14 @@
traceEventStart(<>, %dirty, -1, <>)
}
IW({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>:Test.kt")
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@IW
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt"
index abf76e6..33fa453 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureEarlyExitInInline_Labeled\133useFir = true\135.txt"
@@ -33,14 +33,14 @@
traceEventStart(<>, %dirty, -1, <>)
}
IW({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>:Test.kt")
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@IW
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt"
index ac7376c..0dc5b33 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = false\135.txt"
@@ -34,7 +34,7 @@
}
Text("Root - before", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("M1 - before", %composer, 0b0110)
if (condition) {
@@ -48,7 +48,7 @@
return
}
Text("M1 - after", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Root - after", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt"
index ac7376c..0dc5b33 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testEnsureRuntimeTestWillCompile_CG\133useFir = true\135.txt"
@@ -34,7 +34,7 @@
}
Text("Root - before", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("M1 - before", %composer, 0b0110)
if (condition) {
@@ -48,7 +48,7 @@
return
}
Text("M1 - after", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Root - after", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt"
index ac862b1..e200d6a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt"
@@ -29,14 +29,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val i = <iterator>.next()
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt"
index ac862b1..e200d6a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt"
@@ -29,14 +29,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val i = <iterator>.next()
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = false\135.txt"
index 4155895..720eec5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = false\135.txt"
@@ -29,14 +29,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val i = <iterator>.next()
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = true\135.txt"
index 4155895..720eec5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testForLoopWithCallsInBody\133useFir = true\135.txt"
@@ -29,14 +29,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(i)>")
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val i = <iterator>.next()
P(i, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt"
index 359608f..5799185 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = false\135.txt"
@@ -46,12 +46,12 @@
while (<iterator>.hasNext()) {
val i = <iterator>.next()
val b = a.get(bKey, %composer, 0b00110110)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<get(cK...>")
if (i == 0b0010) {
a.get(cKey, %composer, 0b00110110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt"
index 359608f..5799185 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupAroundExtensionFunctions\133useFir = true\135.txt"
@@ -46,12 +46,12 @@
while (<iterator>.hasNext()) {
val i = <iterator>.next()
val b = a.get(bKey, %composer, 0b00110110)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<get(cK...>")
if (i == 0b0010) {
a.get(cKey, %composer, 0b00110110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt"
index 70e51b9..2cc1338 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = false\135.txt"
@@ -47,7 +47,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
items.forEach { item: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
if (item > -1) {
%composer.startMovableGroup(<>, item)
@@ -63,7 +63,7 @@
%composer.endMovableGroup()
tmp0
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
@@ -90,7 +90,7 @@
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val item = <iterator>.next()
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
if (item > -1) {
%composer.startMovableGroup(<>, item)
@@ -106,7 +106,7 @@
%composer.endMovableGroup()
tmp0
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt"
index 5fbcf02..57e0568 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testGroupsInLoops\133useFir = true\135.txt"
@@ -47,7 +47,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
items.forEach { item: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
if (item > -1) {
%composer.startMovableGroup(<>, item)
@@ -59,7 +59,7 @@
sourceInformationMarkerEnd(%composer)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
@@ -86,7 +86,7 @@
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val item = <iterator>.next()
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
if (item > -1) {
%composer.startMovableGroup(<>, item)
@@ -102,7 +102,7 @@
%composer.endMovableGroup()
tmp0
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = false\135.txt"
index 8b48bc4..d3cb440 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = false\135.txt"
@@ -32,15 +32,15 @@
traceEventStart(<>, %changed, -1, <>)
}
if (x > 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = true\135.txt"
index 8b48bc4..d3cb440 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInBranch\133useFir = true\135.txt"
@@ -32,15 +32,15 @@
traceEventStart(<>, %changed, -1, <>)
}
if (x > 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = false\135.txt"
index 44a9f0a..93b4d57 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = false\135.txt"
@@ -35,24 +35,24 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
- if (%composer.startReplaceableGroup(<>)
+ if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B(a)>")
val tmp0_group = B(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group) {
NA()
- } else if (%composer.startReplaceableGroup(<>)
+ } else if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B(b)>")
val tmp1_group = B(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group) {
NA()
} else {
NA()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = true\135.txt"
index 44a9f0a..93b4d57 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfElseWithCallsInConditions\133useFir = true\135.txt"
@@ -35,24 +35,24 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
- if (%composer.startReplaceableGroup(<>)
+ if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B(a)>")
val tmp0_group = B(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group) {
NA()
- } else if (%composer.startReplaceableGroup(<>)
+ } else if (%composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B(b)>")
val tmp1_group = B(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group) {
NA()
} else {
NA()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = false\135.txt"
index 4673898..59f08b0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = false\135.txt"
@@ -28,12 +28,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
if (x > 0) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = true\135.txt"
index 4673898..59f08b0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithCallsInBranch\133useFir = true\135.txt"
@@ -28,12 +28,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
if (x > 0) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = false\135.txt"
index 40a50be..fe1b30e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = false\135.txt"
@@ -28,17 +28,17 @@
traceEventStart(<>, %changed, -1, <>)
}
run {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Test()>")
if (true) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@run
} else {
Test(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@run
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = true\135.txt"
index 40a50be..fe1b30e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testIfWithEarlyReturnInsideInlineLambda\133useFir = true\135.txt"
@@ -28,17 +28,17 @@
traceEventStart(<>, %changed, -1, <>)
}
run {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Test()>")
if (true) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@run
} else {
Test(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@run
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt"
index 1813dd9..5872e2c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = false\135.txt"
@@ -24,17 +24,17 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
InlineNonComposable {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Test("...>")
repeat(10) { it: Int ->
Test("InsideInline", %composer, 0b0110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val tmp0 = Test("AfterInline", %composer, 0b0110)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt"
index 1813dd9..5872e2c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambdaBeforeACall\133useFir = true\135.txt"
@@ -24,17 +24,17 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
InlineNonComposable {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Test("...>")
repeat(10) { it: Int ->
Test("InsideInline", %composer, 0b0110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val tmp0 = Test("AfterInline", %composer, 0b0110)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = false\135.txt"
index b5e8b9d..12bf825 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = false\135.txt"
@@ -27,18 +27,18 @@
}
Inline1({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Inline...>:Test.kt")
Inline2({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (true) {
%composer.endToMarker(tmp0_marker)
return@Inline1
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = true\135.txt"
index b5e8b9d..12bf825 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineLambda_nonLocalReturn\133useFir = true\135.txt"
@@ -27,18 +27,18 @@
}
Inline1({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Inline...>:Test.kt")
Inline2({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (true) {
%composer.endToMarker(tmp0_marker)
return@Inline1
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = false\135.txt"
index 75bd69e..5024195 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = false\135.txt"
@@ -35,14 +35,14 @@
traceEventStart(<>, %changed, -1, <>)
}
FakeBox({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>:Test.kt")
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@FakeBox
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = true\135.txt"
index 75bd69e..5024195 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInlineReturnLabel\133useFir = true\135.txt"
@@ -35,14 +35,14 @@
traceEventStart(<>, %changed, -1, <>)
}
FakeBox({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>:Test.kt")
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@FakeBox
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt"
index f4a59d1..97e6e7f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = false\135.txt"
@@ -36,7 +36,7 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
@@ -50,7 +50,7 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt"
index f4a59d1..97e6e7f 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun\133useFir = true\135.txt"
@@ -36,7 +36,7 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
@@ -50,7 +50,7 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt"
index 039aae79..3a2c802 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = false\135.txt"
@@ -46,7 +46,7 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (a) {
@@ -60,10 +60,10 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (b) {
@@ -77,7 +77,7 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt"
index 039aae79..3a2c802 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RFun_CM3_RFun\133useFir = true\135.txt"
@@ -46,7 +46,7 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (a) {
@@ -60,10 +60,10 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (b) {
@@ -77,7 +77,7 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt"
index 5861274..8e9c30d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = false\135.txt"
@@ -35,15 +35,15 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M3
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt"
index 5861274..8e9c30d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_RM3\133useFir = true\135.txt"
@@ -35,15 +35,15 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M3
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt"
index 93faaff..3a855da 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = false\135.txt"
@@ -42,26 +42,26 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M3
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M3
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt"
index 93faaff..3a855da 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_CM3_Return_M3_CM3_Return_M3\133useFir = true\135.txt"
@@ -42,26 +42,26 @@
}
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M3
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
M3({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M3
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt"
index ec150c6..66014f8 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = false\135.txt"
@@ -26,7 +26,7 @@
traceEventStart(<>, %changed, -1, <>)
}
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (condition) {
%composer.endToMarker(tmp0_marker)
@@ -35,7 +35,7 @@
}
return@composableLambdaInstance
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt"
index ec150c6..66014f8 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_Lambda\133useFir = true\135.txt"
@@ -26,7 +26,7 @@
traceEventStart(<>, %changed, -1, <>)
}
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (condition) {
%composer.endToMarker(tmp0_marker)
@@ -35,7 +35,7 @@
}
return@composableLambdaInstance
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt"
index 0ae15bf..ba1e034 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = false\135.txt"
@@ -40,10 +40,10 @@
}
A(%composer, 0)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>,<A()>")
while (true) {
A(%composer, 0)
@@ -59,9 +59,9 @@
}
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt"
index 0ae15bf..ba1e034 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M1_W_Return_Func\133useFir = true\135.txt"
@@ -40,10 +40,10 @@
}
A(%composer, 0)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>,<A()>")
while (true) {
A(%composer, 0)
@@ -59,9 +59,9 @@
}
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt"
index 4e5850e..906de43 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = false\135.txt"
@@ -40,13 +40,13 @@
sourceInformationMarkerStart(%composer, <>, "C<A()>,<M1>,<A()>:Test.kt")
A(%composer, 0)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M1
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt"
index 4e5850e..906de43 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M1\133useFir = true\135.txt"
@@ -40,13 +40,13 @@
sourceInformationMarkerStart(%composer, <>, "C<A()>,<M1>,<A()>:Test.kt")
A(%composer, 0)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M1
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt"
index 3fd2128..76d72b5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = false\135.txt"
@@ -38,20 +38,20 @@
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<M1>,<A()>:Test.kt")
A(%composer, 0)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (condition) {
%composer.endToMarker(tmp0_marker)
return@M3
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt"
index 3fd2128..76d72b5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testInline_M3_M1_Return_M3\133useFir = true\135.txt"
@@ -38,20 +38,20 @@
A(%composer, 0)
M3({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<M1>,<A()>:Test.kt")
A(%composer, 0)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
if (condition) {
%composer.endToMarker(tmp0_marker)
return@M3
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = false\135.txt"
index 5c95f9f..0141b32 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
if (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -38,7 +38,7 @@
%composer.endMovableGroup()
A(b, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = true\135.txt"
index 5c95f9f..0141b32 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsAfter\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
if (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -38,7 +38,7 @@
%composer.endMovableGroup()
A(b, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = false\135.txt"
index 4152631e..0f63c6b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
if (x > 0) {
A(a, %composer, 0)
@@ -38,7 +38,7 @@
A(b, %composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = true\135.txt"
index 4152631e..0f63c6b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIfAndCallsBefore\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
if (x > 0) {
A(a, %composer, 0)
@@ -38,7 +38,7 @@
A(b, %composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = false\135.txt"
index 03e5b2f..ccfb16c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = false\135.txt"
@@ -28,7 +28,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
if (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -36,7 +36,7 @@
A(%composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = true\135.txt"
index 03e5b2f..ccfb16c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyInIf\133useFir = true\135.txt"
@@ -28,7 +28,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
if (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -36,7 +36,7 @@
A(%composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = false\135.txt"
index 91509c0..37f70fb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = false\135.txt"
@@ -28,7 +28,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<R()>")
while (x > 0) {
%composer.startMovableGroup(<>, R(%composer, 0))
@@ -36,7 +36,7 @@
A(%composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = true\135.txt"
index 91509c0..37f70fb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testKeyWithComposableValue\133useFir = true\135.txt"
@@ -28,7 +28,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<R()>")
while (x > 0) {
%composer.startMovableGroup(<>, R(%composer, 0))
@@ -36,7 +36,7 @@
A(%composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = false\135.txt"
index 65deee7..9e1a7a6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = false\135.txt"
@@ -25,7 +25,7 @@
traceEventStart(<>, %changed, -1, <>)
}
val factory = createFactory { %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0
}
factory(%composer, 0)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = true\135.txt"
index 65deee7..9e1a7a6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLambdaWithNonUnitResult\133useFir = true\135.txt"
@@ -25,7 +25,7 @@
traceEventStart(<>, %changed, -1, <>)
}
val factory = createFactory { %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
@@ -33,7 +33,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0
}
factory(%composer, 0)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt"
index 7471158..5c540b6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = false\135.txt"
@@ -36,7 +36,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
val tmp0_safe_receiver = x
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(b)>")
val tmp0_group = when {
tmp0_safe_receiver == null -> {
@@ -44,17 +44,17 @@
}
else -> {
tmp0_safe_receiver.let { it: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
if (it > 0) {
A(a, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(b, %composer, 0)
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
A(c, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt"
index 7471158..5c540b6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLetWithComposableCalls\133useFir = true\135.txt"
@@ -36,7 +36,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
val tmp0_safe_receiver = x
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(b)>")
val tmp0_group = when {
tmp0_safe_receiver == null -> {
@@ -44,17 +44,17 @@
}
else -> {
tmp0_safe_receiver.let { it: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
if (it > 0) {
A(a, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(b, %composer, 0)
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
A(c, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = false\135.txt"
index be60c3e..7556d53 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = false\135.txt"
@@ -34,24 +34,24 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
a@while (a.hasNext()) {
val x = a.next()
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
val y = b.next()
if (y == x) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
break@a
}
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = true\135.txt"
index be60c3e..7556d53 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithBreak\133useFir = true\135.txt"
@@ -34,24 +34,24 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
a@while (a.hasNext()) {
val x = a.next()
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
val y = b.next()
if (y == x) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
break@a
}
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = false\135.txt"
index 1d82d7b..aecf15c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = false\135.txt"
@@ -26,7 +26,7 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -37,7 +37,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
A(%composer, 0)
@@ -45,5 +45,5 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = true\135.txt"
index 1d82d7b..aecf15c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testLoopWithReturn\133useFir = true\135.txt"
@@ -26,7 +26,7 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -37,7 +37,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
A(%composer, 0)
@@ -45,5 +45,5 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = false\135.txt"
index b048ac1..9b7a7fe 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = false\135.txt"
@@ -30,18 +30,18 @@
}
Wrapper({ %composer: Composer?, %changed: Int ->
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Leaf(0...>")
repeat(1) { it: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Leaf(0...>")
repeat(1) { it: Int ->
Leaf(0, %composer, 0b0110, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
Leaf(0, %composer, 0b0110, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = true\135.txt"
index b048ac1..9b7a7fe 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testMultipleNestedInlines\133useFir = true\135.txt"
@@ -30,18 +30,18 @@
}
Wrapper({ %composer: Composer?, %changed: Int ->
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Leaf(0...>")
repeat(1) { it: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Leaf(0...>")
repeat(1) { it: Int ->
Leaf(0, %composer, 0b0110, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
Leaf(0, %composer, 0b0110, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = false\135.txt"
index 728f598..5713e7dc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = false\135.txt"
@@ -39,7 +39,7 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -49,7 +49,7 @@
if (x == 0) {
break
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
val y = b.next()
@@ -57,24 +57,24 @@
break
}
if (y == x) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
break@a
}
if (y > 100) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = true\135.txt"
index 9f4feab..9d3b5de 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoopsAndBreak\133useFir = true\135.txt"
@@ -39,7 +39,7 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -49,7 +49,7 @@
if (x == 0) {
break@a
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
val y = b.next()
@@ -57,24 +57,24 @@
break@b
}
if (y == x) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
break@a
}
if (y > 100) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = false\135.txt"
index 7cedd68..8532169 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = false\135.txt"
@@ -30,18 +30,18 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
a@while (a.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = true\135.txt"
index 7cedd68..8532169 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testNestedLoops\133useFir = true\135.txt"
@@ -30,18 +30,18 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
a@while (a.hasNext()) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = false\135.txt"
index 0ee3819..0355a3b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = false\135.txt"
@@ -25,10 +25,10 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>,<B()>")
val tmp0_group = B(%composer, 0) || B(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = true\135.txt"
index 0ee3819..0355a3b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOR\133useFir = true\135.txt"
@@ -25,10 +25,10 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<B()>,<B()>")
val tmp0_group = B(%composer, 0) || B(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt"
index c4a2bf9..dbf6574 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = false\135.txt"
@@ -49,10 +49,10 @@
val l = i
P(i, %composer, 0)
if (i == 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(j)>")
P(j, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
@@ -61,10 +61,10 @@
}
return
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(k)>")
P(k, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
P(l, %composer, 0)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt"
index c4a2bf9..dbf6574 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOrderingOfPushedEndCallsWithEarlyReturns\133useFir = true\135.txt"
@@ -49,10 +49,10 @@
val l = i
P(i, %composer, 0)
if (i == 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(j)>")
P(j, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
@@ -61,10 +61,10 @@
}
return
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(k)>")
P(k, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
P(l, %composer, 0)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = false\135.txt"
index 2458288..25a0cbd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = false\135.txt"
@@ -17,7 +17,7 @@
class SomeClassImpl : SomeClass {
@Composable
override fun SomeFunction(%composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(SomeFunction):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -26,7 +26,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
static val %stable: Int = 0
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = true\135.txt"
index 2458288..25a0cbd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testOverrideWithNonUnitResult\133useFir = true\135.txt"
@@ -17,7 +17,7 @@
class SomeClassImpl : SomeClass {
@Composable
override fun SomeFunction(%composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(SomeFunction):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -26,7 +26,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
static val %stable: Int = 0
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt"
index 31ea2f2..936c9e6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = false\135.txt"
@@ -32,7 +32,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
Test(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<rememb...>")
val tmp1_group = if (param == null) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -44,7 +44,7 @@
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt"
index 31ea2f2..936c9e6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInConditionalCallArgument\133useFir = true\135.txt"
@@ -32,7 +32,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
Test(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<rememb...>")
val tmp1_group = if (param == null) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -44,7 +44,7 @@
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = false\135.txt"
index 4d48d88..f07fc50 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = false\135.txt"
@@ -32,11 +32,11 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0 = Test(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Test(>")
val tmp3_group = if (param == null) {
Test(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<rememb...>")
val tmp2_group = if (param == null) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -48,13 +48,13 @@
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group
}, %composer, 0)
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp3_group
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = true\135.txt"
index 4d48d88..f07fc50 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRememberInNestedConditionalCallArgument\133useFir = true\135.txt"
@@ -32,11 +32,11 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0 = Test(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Test(>")
val tmp3_group = if (param == null) {
Test(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<rememb...>")
val tmp2_group = if (param == null) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -48,13 +48,13 @@
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group
}, %composer, 0)
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp3_group
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt"
index d6d5953..3dede05d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = false\135.txt"
@@ -44,14 +44,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<effect>")
repeat(number) { it: Int ->
effects[it] = effect({
0
}, %composer, 0b0110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
outside = effect({
"0"
}, %composer, 0b0110)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt"
index d6d5953..3dede05d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testRepeatedCallsToEffects\133useFir = true\135.txt"
@@ -44,14 +44,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<effect>")
repeat(number) { it: Int ->
effects[it] = effect({
0
}, %composer, 0b0110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
outside = effect({
"0"
}, %composer, 0b0110)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = false\135.txt"
index 5219109..bd769f2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = false\135.txt"
@@ -33,7 +33,7 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)*<P(i)>,<P(l)>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -45,25 +45,25 @@
val l = i
P(i, %composer, 0)
if (i == 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(j)>")
P(j, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(k)>")
P(k, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
P(l, %composer, 0)
}
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = true\135.txt"
index 5219109..bd769f2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnFromLoop\133useFir = true\135.txt"
@@ -33,7 +33,7 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Example)*<P(i)>,<P(l)>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -45,25 +45,25 @@
val l = i
P(i, %composer, 0)
if (i == 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(j)>")
P(j, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<P(k)>")
P(k, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
P(l, %composer, 0)
}
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = false\135.txt"
index ed747d1..7d750cb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = false\135.txt"
@@ -31,14 +31,14 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0 = <block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
val tmp1_group = x.let { it: Int ->
A(%composer, 0)
val tmp0_return = 123
tmp0_return
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = true\135.txt"
index ed747d1..7d750cb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnInlinedExpressionWithCall\133useFir = true\135.txt"
@@ -31,14 +31,14 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0 = <block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
val tmp1_group = x.let { it: Int ->
A(%composer, 0)
val tmp0_return = 123
tmp0_return
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt"
index 406738b..c958359 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = false\135.txt"
@@ -82,7 +82,7 @@
}
@Composable
fun Test2(b: Boolean, %composer: Composer?, %changed: Int): String? {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Test2):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -92,19 +92,19 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
val tmp0 = null
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
@Composable
fun Test3(b: Boolean, %composer: Composer?, %changed: Int): String? {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Test3):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -114,20 +114,20 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0_return
} else {
val tmp1_return = null
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
@Composable
fun Test4(b: Boolean, %composer: Composer?, %changed: Int): String? {
@@ -174,7 +174,7 @@
}
@Composable
fun Test7(b: Boolean, %composer: Composer?, %changed: Int): String? {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Test7):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -184,14 +184,14 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
val tmp0 = "false"
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
@Composable
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt"
index 2ef96cd..e461327 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testReturnNull\133useFir = true\135.txt"
@@ -82,7 +82,7 @@
}
@Composable
fun Test2(b: Boolean, %composer: Composer?, %changed: Int): String? {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Test2):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -92,19 +92,19 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
val tmp0 = null
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
@Composable
fun Test3(b: Boolean, %composer: Composer?, %changed: Int): String? {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Test3):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -114,20 +114,20 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0_return
} else {
val tmp1_return = null
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
@Composable
fun Test4(b: Boolean, %composer: Composer?, %changed: Int): String? {
@@ -170,7 +170,7 @@
}
@Composable
fun Test7(b: Boolean, %composer: Composer?, %changed: Int): String? {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(Test7):Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -180,14 +180,14 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp1_return
}
val tmp0 = "false"
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
@Composable
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = false\135.txt"
index 33b11fc2..eed4dc6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = false\135.txt"
@@ -28,7 +28,7 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0_safe_receiver = x
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
val tmp0_group = when {
tmp0_safe_receiver == null -> {
@@ -38,7 +38,7 @@
tmp0_safe_receiver.A(%composer, 0b1110 and %changed)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = true\135.txt"
index 33b11fc2..eed4dc6 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSafeCall\133useFir = true\135.txt"
@@ -28,7 +28,7 @@
traceEventStart(<>, %changed, -1, <>)
}
val tmp0_safe_receiver = x
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
val tmp0_group = when {
tmp0_safe_receiver == null -> {
@@ -38,7 +38,7 @@
tmp0_safe_receiver.A(%composer, 0b1110 and %changed)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt"
index 4e5f7ed..a38afd2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = false\135.txt"
@@ -50,12 +50,12 @@
IW({ %composer: Composer?, %changed: Int ->
sourceInformationMarkerStart(%composer, <>, "C<T(2)>,<T(4)>:Test.kt")
T(2, %composer, 0b0110)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<T(3)>")
repeat(3) { it: Int ->
T(3, %composer, 0b0110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
T(4, %composer, 0b0110)
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt"
index 4e5f7ed..a38afd2 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testSourceLineInformationForNormalInline\133useFir = true\135.txt"
@@ -50,12 +50,12 @@
IW({ %composer: Composer?, %changed: Int ->
sourceInformationMarkerStart(%composer, <>, "C<T(2)>,<T(4)>:Test.kt")
T(2, %composer, 0b0110)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<T(3)>")
repeat(3) { it: Int ->
T(3, %composer, 0b0110)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
T(4, %composer, 0b0110)
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = false\135.txt"
index 619a9f7..4963e87 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = false\135.txt"
@@ -61,12 +61,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
@@ -76,28 +76,28 @@
@NonRestartableComposable
@Composable
fun WithReturn(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(WithReturn)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
@NonRestartableComposable
@Composable
@@ -122,12 +122,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = true\135.txt"
index 619a9f7..4963e87 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testTheThing\133useFir = true\135.txt"
@@ -61,12 +61,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
@@ -76,28 +76,28 @@
@NonRestartableComposable
@Composable
fun WithReturn(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(WithReturn)<A()>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
@NonRestartableComposable
@Composable
@@ -122,12 +122,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt"
index af46314..a6f29e1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = false\135.txt"
@@ -34,7 +34,7 @@
}
Text("Some text", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
Identity {
if (condition) {
@@ -48,7 +48,7 @@
return
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Some more text", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt"
index af46314..a6f29e1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1\133useFir = true\135.txt"
@@ -34,7 +34,7 @@
}
Text("Some text", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
Identity {
if (condition) {
@@ -48,7 +48,7 @@
return
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Some more text", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt"
index d924718..042447b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = false\135.txt"
@@ -33,15 +33,15 @@
}
Text("Some text", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
Identity {
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M1
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Some more text", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt"
index d924718..042447b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testVerifyEarlyExitFromNonComposable_M1_RM1\133useFir = true\135.txt"
@@ -33,15 +33,15 @@
}
Text("Some text", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C:Test.kt")
Identity {
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@M1
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Some more text", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = false\135.txt"
index 9681ed7..abdb1fb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = false\135.txt"
@@ -32,20 +32,20 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
when {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(a)>")
val tmp0_group = x == R(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group -> {
NA()
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(b)>")
val tmp1_group = x > R(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group -> {
NA()
}
@@ -53,7 +53,7 @@
NA()
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = true\135.txt"
index 9681ed7..abdb1fb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditionsAndCallAfter\133useFir = true\135.txt"
@@ -32,20 +32,20 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
when {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(a)>")
val tmp0_group = x == R(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group -> {
NA()
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(b)>")
val tmp1_group = x > R(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group -> {
NA()
}
@@ -53,7 +53,7 @@
NA()
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = false\135.txt"
index 2458736..13e1ae3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = false\135.txt"
@@ -32,20 +32,20 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
when {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(a)>")
val tmp0_group = x == R(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group -> {
NA()
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(b)>")
val tmp1_group = x > R(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group -> {
NA()
}
@@ -53,7 +53,7 @@
NA()
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = true\135.txt"
index 2458736..13e1ae3 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInConditions\133useFir = true\135.txt"
@@ -32,20 +32,20 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
when {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(a)>")
val tmp0_group = x == R(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group -> {
NA()
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(b)>")
val tmp1_group = x > R(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group -> {
NA()
}
@@ -53,7 +53,7 @@
NA()
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = false\135.txt"
index 2cee4f4..bc3f736 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = false\135.txt"
@@ -33,21 +33,21 @@
}
when {
x < 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
x > 30 -> {
- %composer.startReplaceableGroup(<>)
- %composer.endReplaceableGroup()
+ %composer.startReplaceGroup(<>)
+ %composer.endReplaceGroup()
NA()
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = true\135.txt"
index 2cee4f4..bc3f736 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCallsInSomeResults\133useFir = true\135.txt"
@@ -33,21 +33,21 @@
}
when {
x < 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
x > 30 -> {
- %composer.startReplaceableGroup(<>)
- %composer.endReplaceableGroup()
+ %composer.startReplaceGroup(<>)
+ %composer.endReplaceGroup()
NA()
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = false\135.txt"
index 6951232..5f0305a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = false\135.txt"
@@ -33,22 +33,22 @@
}
when {
x < 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
x > 30 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(c)>")
A(c, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = true\135.txt"
index 6951232..5f0305a 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithCalls\133useFir = true\135.txt"
@@ -33,22 +33,22 @@
}
when {
x < 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
x > 30 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(c)>")
A(c, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = false\135.txt"
index ec19619..cfff1ad 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = false\135.txt"
@@ -35,24 +35,24 @@
val tmp0_subject = x
when {
tmp0_subject == 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(a)>")
val tmp0_group = R(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
}
tmp0_subject == 0b0001 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(b)>")
val tmp1_group = R(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(c)>")
val tmp2_group = R(c, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = true\135.txt"
index ec19619..cfff1ad 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCallsWithResult\133useFir = true\135.txt"
@@ -35,24 +35,24 @@
val tmp0_subject = x
when {
tmp0_subject == 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(a)>")
val tmp0_group = R(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
}
tmp0_subject == 0b0001 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(b)>")
val tmp1_group = R(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<R(c)>")
val tmp2_group = R(c, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = false\135.txt"
index bad6af4..0a70d3e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = false\135.txt"
@@ -34,22 +34,22 @@
val tmp0_subject = x
when {
tmp0_subject == 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
tmp0_subject == 0b0001 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(c)>")
A(c, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = true\135.txt"
index bad6af4..0a70d3e 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhenWithSubjectAndCalls\133useFir = true\135.txt"
@@ -34,22 +34,22 @@
val tmp0_subject = x
when {
tmp0_subject == 0 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
tmp0_subject == 0b0001 -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
else -> {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(c)>")
A(c, %composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
}
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = false\135.txt"
index b15c231..ff05c971 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = false\135.txt"
@@ -29,18 +29,18 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
if (x > 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
while (x > 0) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = true\135.txt"
index b15c231..ff05c971 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallAfter\133useFir = true\135.txt"
@@ -29,18 +29,18 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
if (x > 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
while (x > 0) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = false\135.txt"
index 69b1c1a..7f98ae5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>,*<A()>")
if (x > 0) {
A(%composer, 0)
@@ -37,7 +37,7 @@
A(%composer, 0)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = true\135.txt"
index 69b1c1a..7f98ae5 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIfAndCallBefore\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>,*<A()>")
if (x > 0) {
A(%composer, 0)
@@ -37,7 +37,7 @@
A(%composer, 0)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = false\135.txt"
index 07965c2..4cf7057 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = false\135.txt"
@@ -28,14 +28,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
if (x > 0) {
while (x > 0) {
A(%composer, 0)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = true\135.txt"
index 07965c2..4cf7057 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileInsideIf\133useFir = true\135.txt"
@@ -28,14 +28,14 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A()>")
if (x > 0) {
while (x > 0) {
A(%composer, 0)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt"
index d5bd839..d44e03b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = false\135.txt"
@@ -31,13 +31,13 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(item...>")
while (items.isNotEmpty()) {
val item = items.removeAt(items.size - 1)
P(item, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt"
index d5bd839..d44e03b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBodyAndCallsAfter\133useFir = true\135.txt"
@@ -31,13 +31,13 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(item...>")
while (items.isNotEmpty()) {
val item = items.removeAt(items.size - 1)
P(item, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = false\135.txt"
index 96a283c..6d5c7fc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = false\135.txt"
@@ -31,13 +31,13 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(item...>")
while (items.isNotEmpty()) {
val item = items.removeAt(items.size - 1)
P(item, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = true\135.txt"
index 96a283c..6d5c7fc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInBody\133useFir = true\135.txt"
@@ -31,13 +31,13 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<P(item...>")
while (items.isNotEmpty()) {
val item = items.removeAt(items.size - 1)
P(item, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = false\135.txt"
index 6d83f67..4719516 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = false\135.txt"
@@ -30,12 +30,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>,<A(a)>")
while (B(%composer, 0)) {
A(a, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(b, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = true\135.txt"
index 6d83f67..4719516 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBodyAndCallsAfter\133useFir = true\135.txt"
@@ -30,12 +30,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>,<A(a)>")
while (B(%composer, 0)) {
A(a, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(b, %composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = false\135.txt"
index eb47a3d..0b7ffbc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = false\135.txt"
@@ -29,12 +29,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>,<A()>")
while (B(%composer, 0)) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = true\135.txt"
index eb47a3d..0b7ffbc 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndBody\133useFir = true\135.txt"
@@ -29,12 +29,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>,<A()>")
while (B(%composer, 0)) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = false\135.txt"
index 836920e..db5ea62 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = false\135.txt"
@@ -29,12 +29,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>")
while (B(%composer, 0)) {
print("hello world")
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = true\135.txt"
index 836920e..db5ea62 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInConditionAndCallsAfter\133useFir = true\135.txt"
@@ -29,12 +29,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>")
while (B(%composer, 0)) {
print("hello world")
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
A(%composer, 0)
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = false\135.txt"
index c84f9e7..116ac66 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = false\135.txt"
@@ -29,12 +29,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>")
while (B(%composer, 0)) {
print("hello world")
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = true\135.txt"
index c84f9e7..116ac66 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileLoopWithCallsInCondition\133useFir = true\135.txt"
@@ -29,12 +29,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<B()>")
while (B(%composer, 0)) {
print("hello world")
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = false\135.txt"
index 822c943..4061c76 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(b)>")
while (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -38,7 +38,7 @@
%composer.endMovableGroup()
A(b, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = true\135.txt"
index 822c943..4061c76 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallAfter\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(b)>")
while (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -38,7 +38,7 @@
%composer.endMovableGroup()
A(b, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = false\135.txt"
index 8feac5a..37404e1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = false\135.txt"
@@ -30,7 +30,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(a)>,<A(c)>")
while (x > 0) {
A(a, %composer, 0)
@@ -40,7 +40,7 @@
%composer.endMovableGroup()
A(c, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = true\135.txt"
index 8feac5a..37404e1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBeforeAndAfter\133useFir = true\135.txt"
@@ -30,7 +30,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(a)>,<A(c)>")
while (x > 0) {
A(a, %composer, 0)
@@ -40,7 +40,7 @@
%composer.endMovableGroup()
A(c, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = false\135.txt"
index d2dae96..42cda15 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = false\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(a)>")
while (x > 0) {
A(a, %composer, 0)
@@ -38,7 +38,7 @@
A(b, %composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = true\135.txt"
index d2dae96..42cda15 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKeyAndCallBefore\133useFir = true\135.txt"
@@ -29,7 +29,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<A(a)>")
while (x > 0) {
A(a, %composer, 0)
@@ -38,7 +38,7 @@
A(b, %composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = false\135.txt"
index 6aa8167..2df0578 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = false\135.txt"
@@ -28,7 +28,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -36,7 +36,7 @@
A(%composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = true\135.txt"
index 6aa8167..2df0578 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithKey\133useFir = true\135.txt"
@@ -28,7 +28,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -36,7 +36,7 @@
A(%composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = false\135.txt"
index 938e6cf..95fd7ed 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = false\135.txt"
@@ -31,7 +31,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -43,7 +43,7 @@
A(b, %composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = true\135.txt"
index 938e6cf..95fd7ed 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/testWhileWithTwoKeys\133useFir = true\135.txt"
@@ -31,7 +31,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
while (x > 0) {
%composer.startMovableGroup(<>, x)
@@ -43,7 +43,7 @@
A(b, %composer, 0)
%composer.endMovableGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt"
index 468d6f3..f895e8b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = false\135.txt"
@@ -40,15 +40,15 @@
}
Text("Root - before", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("M1 - begin", %composer, 0b0110)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Text("...>,<M1>")
if (condition) {
Text("if - begin", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>:Test.kt")
Text("In CCM1", %composer, 0b0110)
%composer.endToMarker(tmp0_marker)
@@ -59,12 +59,12 @@
test_CM1_CCM1_RetFun(condition, %composer, updateChangedFlags(%changed or 0b0001))
}
return
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
Text("M1 - end", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Root - end", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt"
index 468d6f3..f895e8b 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/test_CM1_CCM1_RetFun\133useFir = true\135.txt"
@@ -40,15 +40,15 @@
}
Text("Root - before", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("M1 - begin", %composer, 0b0110)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Text("...>,<M1>")
if (condition) {
Text("if - begin", %composer, 0b0110)
M1({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>:Test.kt")
Text("In CCM1", %composer, 0b0110)
%composer.endToMarker(tmp0_marker)
@@ -59,12 +59,12 @@
test_CM1_CCM1_RetFun(condition, %composer, updateChangedFlags(%changed or 0b0001))
}
return
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
Text("M1 - end", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Root - end", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt"
index e3171f7..ee4e5ea 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt"
@@ -34,11 +34,11 @@
Text("Before outer", %composer, 0b0110)
InlineLinearA({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Inline...>,<Text("...>:Test.kt")
Text("Before inner", %composer, 0b0110)
InlineLinearB({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("Before return", %composer, 0b0110)
if (condition) {
@@ -46,10 +46,10 @@
return@InlineLinearA
}
Text("After return", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("After inner", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Before outer", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt"
index e3171f7..ee4e5ea 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt"
@@ -34,11 +34,11 @@
Text("Before outer", %composer, 0b0110)
InlineLinearA({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Inline...>,<Text("...>:Test.kt")
Text("Before inner", %composer, 0b0110)
InlineLinearB({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("Before return", %composer, 0b0110)
if (condition) {
@@ -46,10 +46,10 @@
return@InlineLinearA
}
Text("After return", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("After inner", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Before outer", %composer, 0b0110)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = false\135.txt"
index c804418..f622ab0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = false\135.txt"
@@ -36,15 +36,15 @@
sourceInformationMarkerStart(%composer, <>, "C<Text("...>,<Inline...>,<Text("...>:Test.kt")
Text("Before inner", %composer, 0b0110)
InlineLinearB({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("Before return", %composer, 0b0110)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@InlineLinearB
}
Text("After return", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("After inner", %composer, 0b0110)
sourceInformationMarkerEnd(%composer)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = true\135.txt"
index c804418..f622ab0 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTests/verifyEarlyExitFromNestedInlineFunction\133useFir = true\135.txt"
@@ -36,15 +36,15 @@
sourceInformationMarkerStart(%composer, <>, "C<Text("...>,<Inline...>,<Text("...>:Test.kt")
Text("Before inner", %composer, 0b0110)
InlineLinearB({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<Text("...>,<Text("...>:Test.kt")
Text("Before return", %composer, 0b0110)
if (condition) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return@InlineLinearB
}
Text("After return", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("After inner", %composer, 0b0110)
sourceInformationMarkerEnd(%composer)
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt"
index 68a2b0f..c8788dd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = false\135.txt"
@@ -30,20 +30,20 @@
Text("Before outer", %composer, 0b0110)
InlineLinearA({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
Text("Before inner", %composer, 0b0110)
InlineLinearB({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
Text("Before return", %composer, 0b0110)
if (condition) {
%composer.endToMarker(tmp0_marker)
return@InlineLinearA
}
Text("After return", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("After inner", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Before outer", %composer, 0b0110)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt"
index 68a2b0f..c8788dd 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.ControlFlowTransformTestsNoSource/verifyEarlyExitFromMultiLevelNestedInlineFunction\133useFir = true\135.txt"
@@ -30,20 +30,20 @@
Text("Before outer", %composer, 0b0110)
InlineLinearA({ %composer: Composer?, %changed: Int ->
val tmp0_marker = %composer.currentMarker
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
Text("Before inner", %composer, 0b0110)
InlineLinearB({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
Text("Before return", %composer, 0b0110)
if (condition) {
%composer.endToMarker(tmp0_marker)
return@InlineLinearA
}
Text("After return", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("After inner", %composer, 0b0110)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
Text("Before outer", %composer, 0b0110)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = false\135.txt"
index 173da83..7ced598 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = false\135.txt"
@@ -17,7 +17,7 @@
fun A(factory: Function2<Composer, Int, Int>) { }
fun B() {
return A { %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
@@ -25,7 +25,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = true\135.txt"
index 173da83..7ced598 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testComposableLambdasWithReturnGetGroups\133useFir = true\135.txt"
@@ -17,7 +17,7 @@
fun A(factory: Function2<Composer, Int, Int>) { }
fun B() {
return A { %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
@@ -25,7 +25,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt"
index 1e95edb..6de1c6d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = false\135.txt"
@@ -63,7 +63,7 @@
class <no name provided> : ButtonColors {
@Composable
override fun getColor(%composer: Composer?, %changed: Int): Color {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(getColor)<condit...>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -76,7 +76,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt"
index 1e95edb..6de1c6d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testFunInterfaces2\133useFir = true\135.txt"
@@ -63,7 +63,7 @@
class <no name provided> : ButtonColors {
@Composable
override fun getColor(%composer: Composer?, %changed: Int): Color {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C(getColor)<condit...>:Test.kt")
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
@@ -76,7 +76,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
return tmp0
}
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt"
index 0d68784..3a0bc0c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = false\135.txt"
@@ -56,15 +56,15 @@
traceEventStart(<>, %changed, -1, <>)
}
if (x > 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(x)>")
A(x, 0, %composer, 0, 0b0010)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(x)>")
A(x, 0, %composer, 0, 0b0010)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt"
index 0d68784..3a0bc0c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testIfInLambda\133useFir = true\135.txt"
@@ -56,15 +56,15 @@
traceEventStart(<>, %changed, -1, <>)
}
if (x > 0) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(x)>")
A(x, 0, %composer, 0, 0b0010)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
} else {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A(x)>")
A(x, 0, %composer, 0, 0b0010)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
if (isTraceInProgress()) {
traceEventEnd()
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = false\135.txt"
index 18102ab..c976626 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = false\135.txt"
@@ -31,22 +31,22 @@
traceEventStart(<>, %changed, -1, <>)
}
Call(%composer, 0)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
val <iterator> = 0 .. 1.iterator()
while (<iterator>.hasNext()) {
val index = <iterator>.next()
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Call()>,<Call()>")
Call(%composer, 0)
if (condition()) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
Call(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = true\135.txt"
index 18102ab..c976626 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testLoopWithContinueAndCallAfter\133useFir = true\135.txt"
@@ -31,22 +31,22 @@
traceEventStart(<>, %changed, -1, <>)
}
Call(%composer, 0)
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "")
val <iterator> = 0 .. 1.iterator()
while (<iterator>.hasNext()) {
val index = <iterator>.next()
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<Call()>,<Call()>")
Call(%composer, 0)
if (condition()) {
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
continue
}
Call(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt"
index f3a5067..0c0f571 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = false\135.txt"
@@ -33,12 +33,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %dirty, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
if (cond) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (cond) {
B(%composer, 0)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt"
index f3a5067..0c0f571 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/testSiblingIfsWithoutElseHaveUniqueKeys\133useFir = true\135.txt"
@@ -33,12 +33,12 @@
if (isTraceInProgress()) {
traceEventStart(<>, %dirty, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<A()>")
if (cond) {
A(%composer, 0)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
if (cond) {
B(%composer, 0)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = false\135.txt"
index 8eedb86..3b8cb66 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = false\135.txt"
@@ -47,13 +47,13 @@
@ComposableInferredTarget(scheme = "[0[0]]")
fun <T> Bug(items: List<T>, content: Function3<@[ParameterName(name = 'item')] T, Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
sourceInformationMarkerStart(%composer, <>, "CC(Bug)P(1):Test.kt")
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<conten...>")
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val item = <iterator>.next()
content(item, %composer, 0b01110000 and %changed)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
sourceInformationMarkerEnd(%composer)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = true\135.txt"
index 587adfa..2381eaa 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTests/test_InlineForLoop\133useFir = true\135.txt"
@@ -47,13 +47,13 @@
@ComposableInferredTarget(scheme = "[0[0]]")
fun <T> Bug(items: List<T>, content: Function3<@[ParameterName(name = 'item')] T, Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
sourceInformationMarkerStart(%composer, <>, "CC(Bug)P(1):Test.kt")
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<conten...>")
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val item = <iterator>.next()
content(item, %composer, 0b01110000 and %changed)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
sourceInformationMarkerEnd(%composer)
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = false\135.txt"
index ed7d170..0d63bde 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = false\135.txt"
@@ -37,11 +37,11 @@
@Composable
@ComposableInferredTarget(scheme = "[0[0]]")
private fun <T> Bug(items: List<T>, content: Function3<@[ParameterName(name = 'item')] T, Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val item = <iterator>.next()
content(item, %composer, 0b01110000 and %changed)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = true\135.txt"
index 2076a4f..0d5f79d 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.FunctionBodySkippingTransformTestsNoSource/test_InlineForLoop_no_source_info\133useFir = true\135.txt"
@@ -37,11 +37,11 @@
@Composable
@ComposableInferredTarget(scheme = "[0[0]]")
private fun <T> Bug(items: List<T>, content: Function3<@[ParameterName(name = 'item')] T, Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
val <iterator> = items.iterator()
while (<iterator>.hasNext()) {
val item = <iterator>.next()
content(item, %composer, 0b01110000 and %changed)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = false\135.txt"
index 1f82a6f..2fa88ce 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = false\135.txt"
@@ -32,7 +32,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
Something(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<{>")
val tmp1_group = if (param != null) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -46,7 +46,7 @@
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = true\135.txt"
index 1f82a6f..2fa88ce 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.LambdaMemoizationTransformTests/testMemoizingFunctionInIf\133useFir = true\135.txt"
@@ -32,7 +32,7 @@
traceEventStart(<>, %dirty, -1, <>)
}
Something(<block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<{>")
val tmp1_group = if (param != null) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -46,7 +46,7 @@
} else {
null
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}, %composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = false\135.txt"
index 5127fc0..4df31fb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = false\135.txt"
@@ -27,7 +27,7 @@
traceEventStart(<>, %changed, -1, <>)
}
val a = <block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<rememb...>")
val tmp1_group = if (x) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -39,7 +39,7 @@
} else {
2
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}
val b = <block>{
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = true\135.txt"
index 5127fc0..4df31fb 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testElidedRememberInsideIfDeoptsRememberAfterIf\133useFir = true\135.txt"
@@ -27,7 +27,7 @@
traceEventStart(<>, %changed, -1, <>)
}
val a = <block>{
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<rememb...>")
val tmp1_group = if (x) {
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
@@ -39,7 +39,7 @@
} else {
2
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
}
val b = <block>{
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = false\135.txt"
index ed9888e..50a53e1 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = false\135.txt"
@@ -22,7 +22,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<rememb...>")
val <iterator> = 0 until count.iterator()
while (<iterator>.hasNext()) {
@@ -36,7 +36,7 @@
tmp0_group
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val a = <block>{
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
val tmp1_group = %composer.cache(false) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = true\135.txt"
index eeb8395..d2f0f67c 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.RememberIntrinsicTransformTests/testRememberInALoop\133useFir = true\135.txt"
@@ -22,7 +22,7 @@
if (isTraceInProgress()) {
traceEventStart(<>, %changed, -1, <>)
}
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<rememb...>")
val <iterator> = 0 until count.iterator()
while (<iterator>.hasNext()) {
@@ -36,7 +36,7 @@
tmp0_group
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val a = <block>{
sourceInformationMarkerStart(%composer, <>, "CC(remember):Test.kt#9igjgp")
val tmp1_group = %composer.cache(false) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt"
index fad6262..0f427c9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = false\135.txt"
@@ -161,7 +161,7 @@
}
one(%composer, 0b1110 and %dirty)
val tmp0_safe_receiver = two
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<invoke...>")
val tmp0_group = when {
tmp0_safe_receiver == null -> {
@@ -171,10 +171,10 @@
tmp0_safe_receiver(%composer, 0b1110 and %dirty shr 0b0011)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
val tmp1_safe_receiver = three
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<it()>")
val tmp1_group = when {
tmp1_safe_receiver == null -> {
@@ -186,10 +186,10 @@
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
val tmp2_safe_receiver = four
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<four()>")
val tmp2_group = when {
tmp2_safe_receiver == null -> {
@@ -201,16 +201,16 @@
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<five()>")
if (five != null) {
five(%composer, 0b1110 and %dirty shr 0b1100)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val tmp3_safe_receiver = six
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Wrappe...>")
val tmp3_group = when {
tmp3_safe_receiver == null -> {
@@ -222,7 +222,7 @@
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp3_group
content(%composer, 0b1110 and %dirty shr 0b00010010)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt"
index fad6262..0f427c9 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TargetAnnotationsTransformTests/testOptionalParameters\133useFir = true\135.txt"
@@ -161,7 +161,7 @@
}
one(%composer, 0b1110 and %dirty)
val tmp0_safe_receiver = two
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<invoke...>")
val tmp0_group = when {
tmp0_safe_receiver == null -> {
@@ -171,10 +171,10 @@
tmp0_safe_receiver(%composer, 0b1110 and %dirty shr 0b0011)
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp0_group
val tmp1_safe_receiver = three
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<it()>")
val tmp1_group = when {
tmp1_safe_receiver == null -> {
@@ -186,10 +186,10 @@
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp1_group
val tmp2_safe_receiver = four
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<four()>")
val tmp2_group = when {
tmp2_safe_receiver == null -> {
@@ -201,16 +201,16 @@
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp2_group
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "<five()>")
if (five != null) {
five(%composer, 0b1110 and %dirty shr 0b1100)
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
val tmp3_safe_receiver = six
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "*<Wrappe...>")
val tmp3_group = when {
tmp3_safe_receiver == null -> {
@@ -222,7 +222,7 @@
}
}
}
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
tmp3_group
content(%composer, 0b1110 and %dirty shr 0b00010010)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt"
index 73bb99b..626f0e42 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = false\135.txt"
@@ -44,7 +44,7 @@
}
A(%composer, 0)
Wrapper({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (!condition) {
@@ -58,7 +58,7 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt" "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt"
index 73bb99b..626f0e42 100644
--- "a/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt"
+++ "b/compose/compiler/compiler-hosted/integration-tests/src/test/resources/golden/androidx.compose.compiler.plugins.kotlin.TraceInformationTest/testInlineFunctionsDonotGenerateTraceMarkers\133useFir = true\135.txt"
@@ -44,7 +44,7 @@
}
A(%composer, 0)
Wrapper({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>)
+ %composer.startReplaceGroup(<>)
sourceInformation(%composer, "C<A()>,<A()>:Test.kt")
A(%composer, 0)
if (!condition) {
@@ -58,7 +58,7 @@
return
}
A(%composer, 0)
- %composer.endReplaceableGroup()
+ %composer.endReplaceGroup()
}, %composer, 0)
A(%composer, 0)
if (isTraceInProgress()) {
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt
index 74d139b..acc6fd3 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/AbstractComposeLowering.kt
@@ -1254,7 +1254,7 @@
}
}
- fun irStartReplaceableGroup(
+ fun irStartReplaceGroup(
currentComposer: IrExpression,
key: IrExpression,
startOffset: Int = UNDEFINED_OFFSET,
@@ -1262,7 +1262,7 @@
): IrExpression {
return irMethodCall(
currentComposer,
- startReplaceableFunction,
+ startReplaceFunction,
startOffset,
endOffset
).also {
@@ -1270,14 +1270,14 @@
}
}
- fun irEndReplaceableGroup(
+ fun irEndReplaceGroup(
currentComposer: IrExpression,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET,
): IrExpression {
return irMethodCall(
currentComposer,
- endReplaceableFunction,
+ endReplaceFunction,
startOffset,
endOffset
)
@@ -1310,17 +1310,21 @@
it.valueParameters.first().type.isNullableAny()
} ?: changedFunction
- val startReplaceableFunction by guardedLazy {
- composerIrClass.functions
+ private val startReplaceFunction by guardedLazy {
+ composerIrClass.functions.firstOrNull {
+ it.name.identifier == "startReplaceGroup" && it.valueParameters.size == 1
+ } ?: composerIrClass.functions
.first {
it.name.identifier == "startReplaceableGroup" && it.valueParameters.size == 1
}
}
- val endReplaceableFunction by guardedLazy {
- composerIrClass.functions
+ private val endReplaceFunction by guardedLazy {
+ composerIrClass.functions.firstOrNull {
+ it.name.identifier == "endReplaceGroup" && it.valueParameters.isEmpty()
+ } ?: composerIrClass.functions
.first {
- it.name.identifier == "endReplaceableGroup" && it.valueParameters.size == 0
+ it.name.identifier == "endReplaceableGroup" && it.valueParameters.isEmpty()
}
}
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
index c960c63..4647e77 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
@@ -312,7 +312,7 @@
*
* There are 3 types of groups in Compose:
*
- * 1. Replaceable Groups
+ * 1. Replace Groups
* 2. Movable Groups
* 3. Restart Groups
*
@@ -322,7 +322,7 @@
*
* 1. If a block executes exactly 1 time always, no groups are needed
* 2. If a set of blocks are such that exactly one of them is executed exactly once (for example,
- * the result blocks of a when clause), then we insert a replaceable group around each block.
+ * the result blocks of a when clause), then we insert a replace group around each block.
* 3. A movable group is only needed if the immediate composable call in the group has a Pivotal
* property.
*
@@ -788,12 +788,12 @@
// At a high level, without useNonSkippingGroupOptimization, a non-restartable composable
// function
- // 1. gets a replaceable group placed around the body
+ // 1. gets a replace group placed around the body
// 2. never calls `$composer.changed(...)` with its parameters
// 3. can have default parameters, so needs to add the defaults preamble if defaults present
// 4. proper groups around control flow structures in the body
// If supported by the runtime and useNonSkippingGroupOptimization is enabled then the
- // replaceable group is not necessary so the above list is changed to,
+ // replace group is not necessary so the above list is changed to,
// 1. never calls `$composer.changed(...)` with its parameters
// 2. can have default parameters, so needs to add the defaults preamble if defaults present
// 3. never elides groups around control flow structures in the body
@@ -860,7 +860,7 @@
scope.realizeGroup {
irComposite(statements = listOfNotNull(
if (emitTraceMarkers) irTraceEventEnd() else null,
- irEndReplaceableGroup(scope = scope)
+ irEndReplaceGroup(scope = scope)
))
}
} else if (useNonSkippingGroupOptimization) {
@@ -874,7 +874,7 @@
listOfNotNull(
when {
outerGroupRequired ->
- irStartReplaceableGroup(
+ irStartReplaceGroup(
body,
scope,
irFunctionSourceKey()
@@ -891,7 +891,7 @@
*bodyPreamble.statements.toTypedArray(),
*transformed.statements.toTypedArray(),
when {
- outerGroupRequired -> irEndReplaceableGroup(scope = scope)
+ outerGroupRequired -> irEndReplaceGroup(scope = scope)
collectSourceInformation && !hasExplicitGroups ->
irSourceInformationMarkerEnd(body, scope)
else -> null
@@ -2020,7 +2020,7 @@
functionSourceKey()
)
- private fun irStartReplaceableGroup(
+ private fun irStartReplaceGroup(
element: IrElement,
scope: Scope.BlockScope,
key: IrExpression = element.irSourceKey(),
@@ -2028,7 +2028,7 @@
endOffset: Int = UNDEFINED_OFFSET
): IrExpression {
return irWithSourceInformation(
- irStartReplaceableGroup(
+ irStartReplaceGroup(
scope.irCurrentComposer(startOffset, endOffset),
key,
startOffset,
@@ -2199,12 +2199,12 @@
)
}
- private fun irEndReplaceableGroup(
+ private fun irEndReplaceGroup(
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET,
scope: Scope.BlockScope
): IrExpression {
- return irEndReplaceableGroup(
+ return irEndReplaceGroup(
scope.irCurrentComposer(startOffset, endOffset),
startOffset,
endOffset
@@ -2299,13 +2299,13 @@
}
}
- private fun IrBlock.withReplaceableGroupStatements(
+ private fun IrBlock.withReplaceGroupStatements(
scope: Scope.BlockScope,
insertAt: Int = 0
): IrExpression {
currentFunctionScope.metrics.recordGroup()
scope.realizeGroup {
- irEndReplaceableGroup(scope = scope)
+ irEndReplaceGroup(scope = scope)
}
val prefix = statements.subList(0, insertAt)
@@ -2319,7 +2319,7 @@
endOffset,
type,
origin,
- prefix + listOf(irStartReplaceableGroup(this, scope)) + suffix
+ prefix + listOf(irStartReplaceGroup(this, scope)) + suffix
)
// otherwise, we want to push an end call for any early returns/jumps, but also add
// an end call to the end of the group
@@ -2329,18 +2329,18 @@
type,
origin,
prefix + listOf(
- irStartReplaceableGroup(
+ irStartReplaceGroup(
this,
scope,
startOffset = startOffset,
endOffset = endOffset
)
- ) + suffix + listOf(irEndReplaceableGroup(startOffset, endOffset, scope))
+ ) + suffix + listOf(irEndReplaceGroup(startOffset, endOffset, scope))
)
}
}
- private fun IrExpression.asReplaceableGroup(scope: Scope.BlockScope): IrExpression {
+ private fun IrExpression.asReplaceGroup(scope: Scope.BlockScope): IrExpression {
currentFunctionScope.metrics.recordGroup()
// if the scope has no composable calls, then the only important thing is that a
// start/end call gets executed. as a result, we can just put them both at the top of
@@ -2349,39 +2349,39 @@
if (!scope.hasComposableCalls && !scope.hasReturn && !scope.hasJump) {
return wrap(
before = listOf(
- irStartReplaceableGroup(
+ irStartReplaceGroup(
this,
scope,
startOffset = startOffset,
endOffset = endOffset,
),
- irEndReplaceableGroup(startOffset, endOffset, scope)
+ irEndReplaceGroup(startOffset, endOffset, scope)
)
)
}
scope.realizeGroup {
- irEndReplaceableGroup(scope = scope)
+ irEndReplaceGroup(scope = scope)
}
return when {
// if the scope ends with a return call, then it will get properly ended if we
// just push the end call on the scope because of the way returns get transformed in
// this class. As a result, here we can safely just "prepend" the start call
endsWithReturnOrJump() -> {
- wrap(before = listOf(irStartReplaceableGroup(this, scope)))
+ wrap(before = listOf(irStartReplaceGroup(this, scope)))
}
// otherwise, we want to push an end call for any early returns/jumps, but also add
// an end call to the end of the group
else -> {
wrap(
before = listOf(
- irStartReplaceableGroup(
+ irStartReplaceGroup(
this,
scope,
startOffset = startOffset,
endOffset = endOffset
)
),
- after = listOf(irEndReplaceableGroup(startOffset, endOffset, scope))
+ after = listOf(irEndReplaceGroup(startOffset, endOffset, scope))
)
}
}
@@ -2427,12 +2427,12 @@
realizeGroup = {
if (before.statements.isEmpty()) {
metrics.recordGroup()
- before.statements.add(irStartReplaceableGroup(this, scope))
- after.statements.add(irEndReplaceableGroup(scope = scope))
+ before.statements.add(irStartReplaceGroup(this, scope))
+ after.statements.add(irEndReplaceGroup(scope = scope))
}
},
makeEnd = {
- irEndReplaceableGroup(scope = scope)
+ irEndReplaceGroup(scope = scope)
}
)
return wrap(
@@ -2456,7 +2456,7 @@
// the group, and we don't have to deal with any of the complicated jump logic that
// could be inside of the block
val makeStart = {
- if (scope.hasInlineEarlyReturn) irStartReplaceableGroup(
+ if (scope.hasInlineEarlyReturn) irStartReplaceGroup(
this,
scope,
startOffset = startOffset,
@@ -2465,7 +2465,7 @@
else irSourceInformationMarkerStart(this, scope)
}
val makeEnd = {
- if (scope.hasInlineEarlyReturn) irEndReplaceableGroup(scope = scope)
+ if (scope.hasInlineEarlyReturn) irEndReplaceGroup(scope = scope)
else irSourceInformationMarkerEnd(this, scope)
}
if (!scope.hasComposableCalls && !scope.hasReturn && !scope.hasJump) {
@@ -3237,9 +3237,9 @@
else
cacheCall.wrap(
before = inputVals.filterNotNull() + listOf(
- irStartReplaceableGroup(expression, blockScope)
+ irStartReplaceGroup(expression, blockScope)
),
- after = listOf(irEndReplaceableGroup(scope = blockScope))
+ after = listOf(irEndReplaceGroup(scope = blockScope))
)
}.also { block ->
if (
@@ -3701,7 +3701,7 @@
withScope(loopScope) {
loop.condition = loop.condition.transform(this, null)
if (loopScope.needsGroupPerIteration && loopScope.hasComposableCalls) {
- loop.condition = loop.condition.asReplaceableGroup(loopScope)
+ loop.condition = loop.condition.asReplaceGroup(loopScope)
}
loop.body = loop.body?.transform(this, null)
@@ -3725,12 +3725,12 @@
val forLoopVariableIndex = current.statements.indexOfFirst {
(it as? IrVariable)?.origin == IrDeclarationOrigin.FOR_LOOP_VARIABLE
}
- loop.body = current.withReplaceableGroupStatements(
+ loop.body = current.withReplaceGroupStatements(
loopScope,
insertAt = forLoopVariableIndex + 1
)
} else {
- loop.body = current?.asReplaceableGroup(loopScope)
+ loop.body = current?.asReplaceGroup(loopScope)
}
}
}
@@ -3759,7 +3759,7 @@
// result branches of the when clause. This is because if we have N branches of a when
// clause, we will always execute exactly 1 result branch, but we will execute 0-N of the
// conditions. This means that if only the results have composable calls, we can use
- // replaceable groups to represent the entire expression. If a condition has a composable
+ // replace groups to represent the entire expression. If a condition has a composable
// call in it, we need to place the whole expression in a Container group, since a variable
// number of them will be created. The exception here is the first branch's condition,
// since it will *always* be executed. As a result, if only the first conditional has a
@@ -3863,7 +3863,7 @@
// to generate a group around it because we will be generating one around the entire
// if statement
if (needsWrappingGroup && condScope.hasComposableCalls) {
- it.condition = it.condition.asReplaceableGroup(condScope)
+ it.condition = it.condition.asReplaceGroup(condScope)
}
if (
// if no wrapping group but more than one result have calls, we have to have every
@@ -3873,7 +3873,7 @@
// the block has composable calls
(needsWrappingGroup && resultScope.hasComposableCalls)
) {
- it.result = it.result.asReplaceableGroup(resultScope)
+ it.result = it.result.asReplaceGroup(resultScope)
}
if (resultsWithCalls == 1 && resultScope.hasComposableCalls) {
@@ -4396,21 +4396,6 @@
else -> super.sourceLocationOf(call)
}
}
-
- class ComposableLambdaScope : BlockScope("composableLambda") {
- override fun calculateHasSourceInformation(sourceInformationEnabled: Boolean): Boolean {
- return sourceInformationEnabled
- }
-
- override fun calculateSourceInfo(sourceInformationEnabled: Boolean): String? =
- if (sourceInformationEnabled) {
- "C${
- super.calculateSourceInfo(sourceInformationEnabled) ?: ""
- }:${functionScope?.function?.sourceFileInformation() ?: ""}"
- } else {
- null
- }
- }
}
inner class IrDefaultBitMaskValueImpl(
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt
index 1ecc29f..ef24c14 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerLambdaMemoization.kt
@@ -1035,9 +1035,9 @@
val cacheTmpVar = irTemporary(cache, "tmpCache")
cacheTmpVar.wrap(
type = expression.type,
- before = listOf(irStartReplaceableGroup(irCurrentComposer(), irConst(key))),
+ before = listOf(irStartReplaceGroup(irCurrentComposer(), irConst(key))),
after = listOf(
- irEndReplaceableGroup(irCurrentComposer()),
+ irEndReplaceGroup(irCurrentComposer()),
irGet(cacheTmpVar)
)
)
diff --git a/compose/foundation/foundation-layout/build.gradle b/compose/foundation/foundation-layout/build.gradle
index 062412b..06cdd0c 100644
--- a/compose/foundation/foundation-layout/build.gradle
+++ b/compose/foundation/foundation-layout/build.gradle
@@ -41,9 +41,10 @@
dependencies {
implementation(libs.kotlinStdlibCommon)
- api(project(":compose:ui:ui"))
- implementation(project(":compose:runtime:runtime"))
+ api("androidx.compose.ui:ui:1.6.0")
+ implementation("androidx.compose.runtime:runtime:1.6.0")
implementation(project(":compose:ui:ui-util"))
+ implementation(project(":compose:ui:ui-unit"))
}
}
@@ -58,7 +59,6 @@
}
}
-
androidMain {
dependsOn(jvmMain)
dependencies {
@@ -73,9 +73,6 @@
dependsOn(jvmMain)
dependencies {
implementation(libs.kotlinStdlib)
-
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:ui:ui-util"))
}
}
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index a7c0ace..6e67e8f 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -127,7 +127,7 @@
public final class FocusableKt {
method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier focusGroup(androidx.compose.ui.Modifier);
- method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+ method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
}
public final class FocusedBoundsKt {
@@ -135,7 +135,7 @@
}
public final class HoverableKt {
- method public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
+ method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
}
public final class ImageKt {
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index 078f45b..4be36a7 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -127,7 +127,7 @@
public final class FocusableKt {
method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier focusGroup(androidx.compose.ui.Modifier);
- method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+ method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
}
public final class FocusedBoundsKt {
@@ -135,7 +135,7 @@
}
public final class HoverableKt {
- method public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
+ method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
}
public final class ImageKt {
diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle
index 8afc1b1..ab1f2c9 100644
--- a/compose/foundation/foundation/build.gradle
+++ b/compose/foundation/foundation/build.gradle
@@ -28,7 +28,6 @@
id("AndroidXPlugin")
id("com.android.library")
id("AndroidXComposePlugin")
- id("AndroidXPaparazziPlugin")
}
@@ -43,11 +42,11 @@
dependencies {
implementation(libs.kotlinStdlibCommon)
api("androidx.collection:collection:1.4.0")
- api(project(':compose:animation:animation'))
- api(project(':compose:runtime:runtime'))
- api(project(':compose:ui:ui'))
- implementation(project(":compose:ui:ui-text"))
- implementation(project(":compose:ui:ui-util"))
+ api(project(":compose:animation:animation"))
+ api("androidx.compose.runtime:runtime:1.6.0")
+ api(project(":compose:ui:ui"))
+ implementation("androidx.compose.ui:ui-text:1.6.0")
+ implementation("androidx.compose.ui:ui-util:1.6.0")
implementation(project(':compose:foundation:foundation-layout'))
}
}
@@ -79,8 +78,6 @@
dependsOn(jvmMain)
dependencies {
implementation(libs.kotlinStdlib)
-
- implementation(project(":compose:ui:ui-util"))
}
}
@@ -124,8 +121,8 @@
implementation(libs.junit)
implementation(libs.truth)
implementation(libs.kotlinReflect)
- implementation(libs.mockitoCore)
- implementation(libs.mockitoKotlin)
+ implementation(libs.mockitoCore4)
+ implementation(libs.mockitoKotlin4)
implementation(project(":constraintlayout:constraintlayout-compose"))
}
}
diff --git a/compose/foundation/foundation/lint-baseline.xml b/compose/foundation/foundation/lint-baseline.xml
index 876590d..d6c663f 100644
--- a/compose/foundation/foundation/lint-baseline.xml
+++ b/compose/foundation/foundation/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanSuppressTag"
@@ -94,17 +94,8 @@
<issue
id="PrimitiveInCollection"
message="field currentKeyPressInteractions with type Map<Key, Press>: replace with LongObjectMap"
- errorLine1=" val currentKeyPressInteractions = mutableMapOf<Key, PressInteraction.Press>()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="return type Map<Key, Press> of getCurrentKeyPressInteractions: replace with LongObjectMap"
- errorLine1=" val currentKeyPressInteractions = mutableMapOf<Key, PressInteraction.Press>()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ errorLine1=" private val currentKeyPressInteractions = mutableMapOf<Key, PressInteraction.Press>()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt"/>
</issue>
@@ -616,15 +607,6 @@
<issue
id="PrimitiveInCollection"
message="field baselineCache with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
- errorLine1=" private var baselineCache: Map<AlignmentLine, Int>? = null"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextAnnotatedStringNode.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field baselineCache with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
errorLine1=" private var baselineCache: MutableMap<AlignmentLine, Int>? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt
index 3143129..38b2b99 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/ClickableTest.kt
@@ -40,6 +40,7 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertModifierIsPure
import androidx.compose.testutils.first
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -2627,6 +2628,111 @@
assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
}
}
+
+ @Test
+ fun composedOverload_nonEquality() {
+ val onClick = {}
+ val modifier1 = Modifier.clickable(onClick = onClick)
+ val modifier2 = Modifier.clickable(onClick = onClick)
+
+ // The composed overload can never compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun nullInteractionSourceNullIndication_equality() {
+ val onClick = {}
+ assertModifierIsPure { toggleInput ->
+ Modifier.clickable(
+ interactionSource = null,
+ indication = null,
+ enabled = toggleInput,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nonNullInteractionSourceNullIndication_equality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ assertModifierIsPure { toggleInput ->
+ Modifier.clickable(
+ interactionSource = interactionSource,
+ indication = null,
+ enabled = toggleInput,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onClick = {}
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.clickable(
+ interactionSource = null,
+ indication = indication,
+ enabled = toggleInput,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nullInteractionSourceNonNullIndication_nonEquality() {
+ val onClick = {}
+ val indication = TestIndication {}
+ val modifier1 = Modifier.clickable(
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+ val modifier2 = Modifier.clickable(
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun nonNullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.clickable(
+ interactionSource = interactionSource,
+ indication = indication,
+ enabled = toggleInput,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nonNullInteractionSourceNonNullIndication_nonEquality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndication {}
+ val modifier1 = Modifier.clickable(
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+ val modifier2 = Modifier.clickable(
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
}
/**
@@ -2635,7 +2741,7 @@
* @param onCreate lambda executed when the instance is created with [rememberUpdatedInstance]
*/
@Suppress("DEPRECATION_ERROR")
-private class TestIndication(val onCreate: (InteractionSource) -> Unit) : Indication {
+internal class TestIndication(val onCreate: (InteractionSource) -> Unit) : Indication {
@Deprecated("Super method is deprecated")
@Composable
override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt
index d1ebf73..38724ad 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/FocusableTest.kt
@@ -35,6 +35,7 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertModifierIsPure
import androidx.compose.testutils.first
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -482,6 +483,17 @@
}
@Test
+ fun focusable_equality() {
+ val interactionSource = MutableInteractionSource()
+ assertModifierIsPure { toggleInput ->
+ Modifier.focusable(
+ enabled = toggleInput,
+ interactionSource = interactionSource,
+ )
+ }
+ }
+
+ @Test
fun focusable_requestsBringIntoView_whenFocused() {
// Arrange.
val requestedRects = mutableListOf<Rect?>()
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/HoverableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/HoverableTest.kt
index 5f0322e..cc2a51c 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/HoverableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/HoverableTest.kt
@@ -27,6 +27,7 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertModifierIsPure
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@@ -69,7 +70,7 @@
}
@Test
- fun hoverableText_testInspectorValue() {
+ fun hoverableTest_testInspectorValue() {
rule.setContent {
val interactionSource = remember { MutableInteractionSource() }
val modifier = Modifier.hoverable(interactionSource) as InspectableValue
@@ -83,6 +84,17 @@
}
}
+ @Test
+ fun hoverableTest_equality() {
+ val interactionSource = MutableInteractionSource()
+ assertModifierIsPure { toggleInput ->
+ Modifier.hoverable(
+ interactionSource = interactionSource,
+ enabled = toggleInput,
+ )
+ }
+ }
+
@OptIn(ExperimentalTestApi::class)
@ExperimentalComposeUiApi
@Test
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridBeyondBoundsTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridBeyondBoundsTest.kt
index fda112e..5eccf0b 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridBeyondBoundsTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridBeyondBoundsTest.kt
@@ -22,8 +22,11 @@
import androidx.compose.foundation.lazy.list.TrackPlacedElement
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
+import androidx.compose.testutils.ParameterizedComposeTestRule
+import androidx.compose.testutils.createParameterizedComposeTestRule
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
@@ -37,8 +40,6 @@
import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout
import androidx.compose.ui.modifier.modifierLocalConsumer
import androidx.compose.ui.platform.LocalLayoutDirection
-import androidx.compose.ui.test.junit4.ComposeContentTestRule
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.LayoutDirection.Ltr
@@ -47,16 +48,13 @@
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
@OptIn(ExperimentalComposeUiApi::class)
@MediumTest
-@RunWith(Parameterized::class)
-class LazyStaggeredGridBeyondBoundsTest(param: Param) {
+class LazyStaggeredGridBeyondBoundsTest {
@get:Rule
- val rule = createComposeRule()
+ val rule = createParameterizedComposeTestRule<Param>()
// We need to wrap the inline class parameter in another class because Java can't instantiate
// the inline class.
@@ -68,21 +66,18 @@
override fun toString() = "beyondBoundsLayoutDirection=$beyondBoundsLayoutDirection " +
"reverseLayout=$reverseLayout " +
"layoutDirection=$layoutDirection"
+
+ internal fun placementComparator(): PlacementComparator {
+ return PlacementComparator(beyondBoundsLayoutDirection, layoutDirection, reverseLayout)
+ }
}
- private val beyondBoundsLayoutDirection = param.beyondBoundsLayoutDirection
- private val reverseLayout = param.reverseLayout
- private val layoutDirection = param.layoutDirection
private val placedItems = sortedMapOf<Int, Rect>()
private var beyondBoundsLayout: BeyondBoundsLayout? = null
private lateinit var lazyStaggeredGridState: LazyStaggeredGridState
- private val placementComparator =
- PlacementComparator(beyondBoundsLayoutDirection, layoutDirection, reverseLayout)
companion object {
- @JvmStatic
- @Parameterized.Parameters(name = "{0}")
- fun initParameters() = buildList {
+ val ParamsToTest = buildList {
for (beyondBoundsLayoutDirection in listOf(Left, Right, Above, Below, Before, After)) {
for (reverseLayout in listOf(false, true)) {
for (layoutDirection in listOf(Ltr, Rtl)) {
@@ -93,6 +88,11 @@
}
}
+ private fun resetTestCase() {
+ placedItems.clear()
+ beyondBoundsLayout = null
+ }
+
@Test
fun onlyOneVisibleItemIsPlaced() {
// Arrange.
@@ -107,9 +107,14 @@
}
// Assert.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(0)
- assertThat(visibleItems).containsExactly(0)
+ with(rule) {
+ forEachParameter(ParamsToTest) {
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(0)
+ assertThat(visibleItems).containsExactly(0)
+ }
+ resetTestCase()
+ }
}
}
@@ -127,9 +132,14 @@
}
// Assert.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(0, 1)
- assertThat(visibleItems).containsExactly(0, 1)
+ with(rule) {
+ forEachParameter(ParamsToTest) {
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(0, 1)
+ assertThat(visibleItems).containsExactly(0, 1)
+ }
+ resetTestCase()
+ }
}
}
@@ -147,9 +157,14 @@
}
// Assert.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(0, 1, 2)
- assertThat(visibleItems).containsExactly(0, 1, 2)
+ with(rule) {
+ forEachParameter(ParamsToTest) {
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(0, 1, 2)
+ assertThat(visibleItems).containsExactly(0, 1, 2)
+ }
+ resetTestCase()
+ }
}
}
@@ -169,22 +184,29 @@
}
}
}
- rule.runOnIdle {
- beyondBoundsLayoutRef = beyondBoundsLayout!!
- addItems = false
- }
- // Act.
- val hasMoreContent = rule.runOnIdle {
- beyondBoundsLayoutRef.layout(beyondBoundsLayoutDirection) {
- hasMoreContent
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ runOnIdle {
+ beyondBoundsLayoutRef = beyondBoundsLayout!!
+ addItems = false
+ }
+
+ // Act.
+ val hasMoreContent = rule.runOnIdle {
+ beyondBoundsLayoutRef.layout(param.beyondBoundsLayoutDirection) {
+ hasMoreContent
+ }
+ }
+
+ // Assert.
+ runOnIdle {
+ assertThat(hasMoreContent).isFalse()
+ }
+ resetTestCase()
+ addItems = true
}
}
-
- // Assert.
- rule.runOnIdle {
- assertThat(hasMoreContent).isFalse()
- }
}
@Test
@@ -199,188 +221,6 @@
)
}
item {
- Box(Modifier
- .size(10.toDp())
- .trackPlaced(5)
- .modifierLocalConsumer {
- beyondBoundsLayout = ModifierLocalBeyondBoundsLayout.current
- }
- )
- }
- items(5) { index ->
- Box(
- Modifier
- .size(10.toDp())
- .trackPlaced(index + 6)
- )
- }
- }
-
- // Act.
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- // Assert that the beyond bounds items are present.
- if (expectedExtraItemsBeforeVisibleBounds()) {
- assertThat(placedItems.keys).containsExactly(4, 5, 6, 7)
- } else {
- assertThat(placedItems.keys).containsExactly(5, 6, 7, 8)
- }
- assertThat(visibleItems).containsExactly(5, 6, 7)
-
- assertThat(placedItems.values).isInOrder(placementComparator)
-
- // Just return true so that we stop as soon as we run this once.
- // This should result in one extra item being added.
- true
- }
- }
-
- // Assert that the beyond bounds items are removed.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(5, 6, 7)
- assertThat(visibleItems).containsExactly(5, 6, 7)
- }
- }
-
- @Test
- fun oneExtraItemBeyondVisibleBounds_multipleCells() {
- val itemSize = 50
- val itemSizeDp = itemSize.toDp()
- // Arrange.
- rule.setLazyContent(cells = 2, size = itemSizeDp * 3, firstVisibleItem = 10) {
- // item | item | x5
- // item | local | x1
- // item | item | x5
- items(11) { index ->
- Box(
- Modifier
- .size(itemSizeDp)
- .trackPlaced(index)
- )
- }
- item {
- Box(Modifier
- .size(itemSizeDp)
- .trackPlaced(11)
- .modifierLocalConsumer {
- beyondBoundsLayout = ModifierLocalBeyondBoundsLayout.current
- }
- )
- }
- items(10) { index ->
- Box(
- Modifier
- .size(itemSizeDp)
- .trackPlaced(index + 12)
- )
- }
- }
-
- // Act.
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- // Assert that the beyond bounds items are present.
- if (expectedExtraItemsBeforeVisibleBounds()) {
- assertThat(placedItems.keys).containsExactly(9, 10, 11, 12, 13, 14, 15)
- } else {
- assertThat(placedItems.keys).containsExactly(10, 11, 12, 13, 14, 15, 16)
- }
- assertThat(visibleItems).containsExactly(10, 11, 12, 13, 14, 15)
-
- assertThat(placedItems.values).isInOrder(placementComparator)
-
- // Just return true so that we stop as soon as we run this once.
- // This should result in one extra item being added.
- true
- }
- }
-
- // Assert that the beyond bounds items are removed.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(10, 11, 12, 13, 14, 15)
- assertThat(visibleItems).containsExactly(10, 11, 12, 13, 14, 15)
- }
- }
-
- @Test
- fun oneExtraItemBeyondVisibleBounds_multipleCells_staggered() {
- val itemSize = 50
- val itemSizeDp = itemSize.toDp()
- // Arrange.
- rule.setLazyContent(cells = 3, size = itemSizeDp * 2, firstVisibleItem = 4) {
- // -------------
- // | | 1 | |
- // | 0 |---| 2 |
- // | | 3 | |
- // |-----------|
- // | 4 |
- // |-----------|
- // | | 6 | |
- // | 5 |---| 7 |
- // | | 8 | |
- // -------------
- items(4) { index ->
- Box(
- Modifier
- .size(itemSizeDp * if (index % 2 == 0) 2f else 1f)
- .trackPlaced(index)
- )
- }
- item(span = StaggeredGridItemSpan.FullLine) {
- Box(Modifier
- .size(itemSizeDp)
- .trackPlaced(4)
- .modifierLocalConsumer {
- beyondBoundsLayout = ModifierLocalBeyondBoundsLayout.current
- }
- )
- }
- items(4) { index ->
- Box(
- Modifier
- .size(itemSizeDp * if (index % 2 == 0) 2f else 1f)
- .trackPlaced(index + 5)
- )
- }
- }
-
- // Act.
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- // Assert that the beyond bounds items are present.
- if (expectedExtraItemsBeforeVisibleBounds()) {
- assertThat(placedItems.keys).containsExactly(3, 4, 5, 6, 7)
- assertThat(visibleItems).containsExactly(4, 5, 6, 7)
- } else {
- assertThat(placedItems.keys).containsExactly(4, 5, 6, 7, 8)
- assertThat(visibleItems).containsExactly(4, 5, 6, 7)
- }
- // Just return true so that we stop as soon as we run this once.
- // This should result in one extra item being added.
- true
- }
- }
-
- // Assert that the beyond bounds items are removed.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(4, 5, 6, 7)
- assertThat(visibleItems).containsExactly(4, 5, 6, 7)
- }
- }
-
- @Test
- fun twoExtraItemsBeyondVisibleBounds() {
- // Arrange.
- var extraItemCount = 2
- rule.setLazyContent(size = 30.toDp(), firstVisibleItem = 5) {
- items(5) { index ->
- Box(
- Modifier
- .size(10.toDp())
- .trackPlaced(index)
- )
- }
- item {
Box(
Modifier
.size(10.toDp())
@@ -400,32 +240,237 @@
}
// Act.
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- if (--extraItemCount > 0) {
- // Return null to continue the search.
- null
- } else {
- // Assert that the beyond bounds items are present.
- if (expectedExtraItemsBeforeVisibleBounds()) {
- assertThat(placedItems.keys).containsExactly(3, 4, 5, 6, 7)
- } else {
- assertThat(placedItems.keys).containsExactly(5, 6, 7, 8, 9)
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ // Assert that the beyond bounds items are present.
+ if (param.expectedExtraItemsBeforeVisibleBounds()) {
+ assertThat(placedItems.keys).containsExactly(4, 5, 6, 7)
+ } else {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7, 8)
+ }
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+
+ assertThat(placedItems.values).isInOrder(param.placementComparator())
+
+ // Just return true so that we stop as soon as we run this once.
+ // This should result in one extra item being added.
+ true
}
- assertThat(visibleItems).containsExactly(5, 6, 7)
-
- assertThat(placedItems.values).isInOrder(placementComparator)
-
- // Return true to stop the search.
- true
}
+
+ // Assert that the beyond bounds items are removed.
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ }
+ resetTestCase()
+ }
+ }
+ }
+
+ @Test
+ fun oneExtraItemBeyondVisibleBounds_multipleCells() {
+ val itemSize = 50
+ val itemSizeDp = itemSize.toDp()
+ // Arrange.
+ rule.setLazyContent(cells = 2, size = itemSizeDp * 3, firstVisibleItem = 10) {
+ // item | item | x5
+ // item | local | x1
+ // item | item | x5
+ items(11) { index ->
+ Box(
+ Modifier
+ .size(itemSizeDp)
+ .trackPlaced(index)
+ )
+ }
+ item {
+ Box(
+ Modifier
+ .size(itemSizeDp)
+ .trackPlaced(11)
+ .modifierLocalConsumer {
+ beyondBoundsLayout = ModifierLocalBeyondBoundsLayout.current
+ }
+ )
+ }
+ items(10) { index ->
+ Box(
+ Modifier
+ .size(itemSizeDp)
+ .trackPlaced(index + 12)
+ )
}
}
- // Assert that the beyond bounds items are removed.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(5, 6, 7)
- assertThat(visibleItems).containsExactly(5, 6, 7)
+ // Act.
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ // Assert that the beyond bounds items are present.
+ if (param.expectedExtraItemsBeforeVisibleBounds()) {
+ assertThat(placedItems.keys).containsExactly(9, 10, 11, 12, 13, 14, 15)
+ } else {
+ assertThat(placedItems.keys).containsExactly(10, 11, 12, 13, 14, 15, 16)
+ }
+ assertThat(visibleItems).containsExactly(10, 11, 12, 13, 14, 15)
+
+ assertThat(placedItems.values).isInOrder(param.placementComparator())
+
+ // Just return true so that we stop as soon as we run this once.
+ // This should result in one extra item being added.
+ true
+ }
+ }
+
+ // Assert that the beyond bounds items are removed.
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(10, 11, 12, 13, 14, 15)
+ assertThat(visibleItems).containsExactly(10, 11, 12, 13, 14, 15)
+ }
+ resetTestCase()
+ }
+ }
+ }
+
+ @Test
+ fun oneExtraItemBeyondVisibleBounds_multipleCells_staggered() {
+ val itemSize = 50
+ val itemSizeDp = itemSize.toDp()
+ // Arrange.
+ rule.setLazyContent(cells = 3, size = itemSizeDp * 2, firstVisibleItem = 4) {
+ // -------------
+ // | | 1 | |
+ // | 0 |---| 2 |
+ // | | 3 | |
+ // |-----------|
+ // | 4 |
+ // |-----------|
+ // | | 6 | |
+ // | 5 |---| 7 |
+ // | | 8 | |
+ // -------------
+ items(4) { index ->
+ Box(
+ Modifier
+ .size(itemSizeDp * if (index % 2 == 0) 2f else 1f)
+ .trackPlaced(index)
+ )
+ }
+ item(span = StaggeredGridItemSpan.FullLine) {
+ Box(
+ Modifier
+ .size(itemSizeDp)
+ .trackPlaced(4)
+ .modifierLocalConsumer {
+ beyondBoundsLayout = ModifierLocalBeyondBoundsLayout.current
+ }
+ )
+ }
+ items(4) { index ->
+ Box(
+ Modifier
+ .size(itemSizeDp * if (index % 2 == 0) 2f else 1f)
+ .trackPlaced(index + 5)
+ )
+ }
+ }
+
+ // Act.
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ // Assert that the beyond bounds items are present.
+ if (param.expectedExtraItemsBeforeVisibleBounds()) {
+ assertThat(placedItems.keys).containsExactly(3, 4, 5, 6, 7)
+ assertThat(visibleItems).containsExactly(4, 5, 6, 7)
+ } else {
+ assertThat(placedItems.keys).containsExactly(4, 5, 6, 7, 8)
+ assertThat(visibleItems).containsExactly(4, 5, 6, 7)
+ }
+ // Just return true so that we stop as soon as we run this once.
+ // This should result in one extra item being added.
+ true
+ }
+ }
+
+ // Assert that the beyond bounds items are removed.
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(4, 5, 6, 7)
+ assertThat(visibleItems).containsExactly(4, 5, 6, 7)
+ }
+ resetTestCase()
+ }
+ }
+ }
+
+ @Test
+ fun twoExtraItemsBeyondVisibleBounds() {
+ // Arrange.
+ rule.setLazyContent(size = 30.toDp(), firstVisibleItem = 5) {
+ items(5) { index ->
+ Box(
+ Modifier
+ .size(10.toDp())
+ .trackPlaced(index)
+ )
+ }
+ item {
+ Box(
+ Modifier
+ .size(10.toDp())
+ .trackPlaced(5)
+ .modifierLocalConsumer {
+ beyondBoundsLayout = ModifierLocalBeyondBoundsLayout.current
+ }
+ )
+ }
+ items(5) { index ->
+ Box(
+ Modifier
+ .size(10.toDp())
+ .trackPlaced(index + 6)
+ )
+ }
+ }
+
+ // Act.
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ var extraItemCount = 2
+ runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ if (--extraItemCount > 0) {
+ // Return null to continue the search.
+ null
+ } else {
+ // Assert that the beyond bounds items are present.
+ if (param.expectedExtraItemsBeforeVisibleBounds()) {
+ assertThat(placedItems.keys).containsExactly(3, 4, 5, 6, 7)
+ } else {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7, 8, 9)
+ }
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+
+ assertThat(placedItems.values).isInOrder(param.placementComparator())
+
+ // Return true to stop the search.
+ true
+ }
+ }
+ }
+
+ // Assert that the beyond bounds items are removed.
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ }
+ resetTestCase()
+ }
}
}
@@ -460,39 +505,45 @@
}
// Act.
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- if (hasMoreContent) {
- // Just return null so that we keep adding more items till we reach the end.
- null
- } else {
- // Assert that the beyond bounds items are present.
- if (expectedExtraItemsBeforeVisibleBounds()) {
- assertThat(placedItems.keys).containsExactly(0, 1, 2, 3, 4, 5, 6, 7)
- } else {
- assertThat(placedItems.keys).containsExactly(5, 6, 7, 8, 9, 10)
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ if (hasMoreContent) {
+ // Just return null so that we keep adding more items till we reach the end.
+ null
+ } else {
+ // Assert that the beyond bounds items are present.
+ if (param.expectedExtraItemsBeforeVisibleBounds()) {
+ assertThat(placedItems.keys).containsExactly(0, 1, 2, 3, 4, 5, 6, 7)
+ } else {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7, 8, 9, 10)
+ }
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+
+ // Verify if the placed item offsets are in order.
+ assertThat(
+ placedItems.toSortedMap().values
+ ).isInOrder(param.placementComparator())
+
+ // Return true to end the search.
+ true
+ }
}
- assertThat(visibleItems).containsExactly(5, 6, 7)
-
- // Verify if the placed item offsets are in order.
- assertThat(placedItems.toSortedMap().values).isInOrder(placementComparator)
-
- // Return true to end the search.
- true
}
- }
- }
- // Assert that the beyond bounds items are removed.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ // Assert that the beyond bounds items are removed.
+ runOnIdle {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ }
+ resetTestCase()
+ }
}
}
@Test
fun beyondBoundsLayoutRequest_inDirectionPerpendicularToLazyListOrientation() {
// Arrange.
- var beyondBoundsLayoutCount = 0
rule.setLazyContentInPerpendicularDirection(size = 30.toDp(), firstVisibleItem = 5) {
items(5) { index ->
Box(
@@ -519,49 +570,58 @@
)
}
}
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(5, 6, 7)
- assertThat(visibleItems).containsExactly(5, 6, 7)
- }
-
- // Act.
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- beyondBoundsLayoutCount++
- when (beyondBoundsLayoutDirection) {
- Left, Right, Above, Below -> {
- assertThat(placedItems.keys).containsExactly(5, 6, 7)
- assertThat(visibleItems).containsExactly(5, 6, 7)
- }
- Before, After -> {
- if (expectedExtraItemsBeforeVisibleBounds()) {
- assertThat(placedItems.keys).containsExactly(4, 5, 6, 7)
- assertThat(visibleItems).containsExactly(5, 6, 7)
- } else {
- assertThat(placedItems.keys).containsExactly(5, 6, 7, 8)
- assertThat(visibleItems).containsExactly(5, 6, 7)
- }
- }
- }
- // Just return true so that we stop as soon as we run this once.
- // This should result in one extra item being added.
- true
- }
- }
-
- rule.runOnIdle {
- when (beyondBoundsLayoutDirection) {
- Left, Right, Above, Below -> {
- assertThat(beyondBoundsLayoutCount).isEqualTo(0)
- }
- Before, After -> {
- assertThat(beyondBoundsLayoutCount).isEqualTo(1)
-
- // Assert that the beyond bounds items are removed.
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ var beyondBoundsLayoutCount = 0
+ runOnIdle {
assertThat(placedItems.keys).containsExactly(5, 6, 7)
assertThat(visibleItems).containsExactly(5, 6, 7)
}
- else -> error("Unsupported BeyondBoundsLayoutDirection")
+
+ // Act.
+ runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ beyondBoundsLayoutCount++
+ when (param.beyondBoundsLayoutDirection) {
+ Left, Right, Above, Below -> {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ }
+
+ Before, After -> {
+ if (param.expectedExtraItemsBeforeVisibleBounds()) {
+ assertThat(placedItems.keys).containsExactly(4, 5, 6, 7)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ } else {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7, 8)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ }
+ }
+ }
+ // Just return true so that we stop as soon as we run this once.
+ // This should result in one extra item being added.
+ true
+ }
+ }
+
+ runOnIdle {
+ when (param.beyondBoundsLayoutDirection) {
+ Left, Right, Above, Below -> {
+ assertThat(beyondBoundsLayoutCount).isEqualTo(0)
+ }
+
+ Before, After -> {
+ assertThat(beyondBoundsLayoutCount).isEqualTo(1)
+
+ // Assert that the beyond bounds items are removed.
+ assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ }
+
+ else -> error("Unsupported BeyondBoundsLayoutDirection")
+ }
+ }
+ resetTestCase()
}
}
}
@@ -597,81 +657,95 @@
}
// Act.
- var count = 0
- rule.runOnUiThread {
- beyondBoundsLayout!!.layout(beyondBoundsLayoutDirection) {
- // Assert that we don't keep iterating when there is no ending condition.
- assertThat(count++).isLessThan(lazyStaggeredGridState.layoutInfo.totalItemsCount)
- // Always return null to continue the search.
- null
- }
- }
+ with(rule) {
+ forEachParameter(ParamsToTest) { param ->
+ var count = 0
+ rule.runOnUiThread {
+ beyondBoundsLayout!!.layout(param.beyondBoundsLayoutDirection) {
+ // Assert that we don't keep iterating when there is no ending condition.
+ assertThat(count++)
+ .isLessThan(lazyStaggeredGridState.layoutInfo.totalItemsCount)
+ // Always return null to continue the search.
+ null
+ }
+ }
- // Assert that the beyond bounds items are removed.
- rule.runOnIdle {
- assertThat(placedItems.keys).containsExactly(5, 6, 7)
- assertThat(visibleItems).containsExactly(5, 6, 7)
+ // Assert that the beyond bounds items are removed.
+ rule.runOnIdle {
+ assertThat(placedItems.keys).containsExactly(5, 6, 7)
+ assertThat(visibleItems).containsExactly(5, 6, 7)
+ }
+ resetTestCase()
+ }
}
}
- private fun ComposeContentTestRule.setLazyContent(
+ private fun ParameterizedComposeTestRule<Param>.setLazyContent(
size: Dp,
firstVisibleItem: Int,
cells: Int = 1,
content: LazyStaggeredGridScope.() -> Unit
) {
setContent {
- CompositionLocalProvider(LocalLayoutDirection provides layoutDirection) {
- lazyStaggeredGridState = rememberLazyStaggeredGridState(firstVisibleItem)
- when (beyondBoundsLayoutDirection) {
- Left, Right, Before, After ->
- LazyHorizontalStaggeredGrid(
- rows = StaggeredGridCells.Fixed(cells),
- modifier = Modifier.size(size),
- state = lazyStaggeredGridState,
- reverseLayout = reverseLayout,
- content = content
- )
- Above, Below ->
- LazyVerticalStaggeredGrid(
- columns = StaggeredGridCells.Fixed(cells),
- modifier = Modifier.size(size),
- state = lazyStaggeredGridState,
- reverseLayout = reverseLayout,
- content = content
- )
- else -> unsupportedDirection()
+ key(it) {
+ CompositionLocalProvider(LocalLayoutDirection provides it.layoutDirection) {
+ lazyStaggeredGridState = rememberLazyStaggeredGridState(firstVisibleItem)
+ when (it.beyondBoundsLayoutDirection) {
+ Left, Right, Before, After ->
+ LazyHorizontalStaggeredGrid(
+ rows = StaggeredGridCells.Fixed(cells),
+ modifier = Modifier.size(size),
+ state = lazyStaggeredGridState,
+ reverseLayout = it.reverseLayout,
+ content = content
+ )
+
+ Above, Below ->
+ LazyVerticalStaggeredGrid(
+ columns = StaggeredGridCells.Fixed(cells),
+ modifier = Modifier.size(size),
+ state = lazyStaggeredGridState,
+ reverseLayout = it.reverseLayout,
+ content = content
+ )
+
+ else -> unsupportedDirection()
+ }
}
}
}
}
- private fun ComposeContentTestRule.setLazyContentInPerpendicularDirection(
+ private fun ParameterizedComposeTestRule<Param>.setLazyContentInPerpendicularDirection(
size: Dp,
firstVisibleItem: Int,
content: LazyStaggeredGridScope.() -> Unit
) {
setContent {
- CompositionLocalProvider(LocalLayoutDirection provides layoutDirection) {
- lazyStaggeredGridState = rememberLazyStaggeredGridState(firstVisibleItem)
- when (beyondBoundsLayoutDirection) {
- Left, Right, Before, After ->
- LazyVerticalStaggeredGrid(
- columns = StaggeredGridCells.Fixed(1),
- modifier = Modifier.size(size),
- state = lazyStaggeredGridState,
- reverseLayout = reverseLayout,
- content = content
- )
- Above, Below ->
- LazyHorizontalStaggeredGrid(
- rows = StaggeredGridCells.Fixed(1),
- modifier = Modifier.size(size),
- state = lazyStaggeredGridState,
- reverseLayout = reverseLayout,
- content = content
- )
- else -> unsupportedDirection()
+ key(it) {
+ CompositionLocalProvider(LocalLayoutDirection provides it.layoutDirection) {
+ lazyStaggeredGridState = rememberLazyStaggeredGridState(firstVisibleItem)
+ when (it.beyondBoundsLayoutDirection) {
+ Left, Right, Before, After ->
+ LazyVerticalStaggeredGrid(
+ columns = StaggeredGridCells.Fixed(1),
+ modifier = Modifier.size(size),
+ state = lazyStaggeredGridState,
+ reverseLayout = it.reverseLayout,
+ content = content
+ )
+
+ Above, Below ->
+ LazyHorizontalStaggeredGrid(
+ rows = StaggeredGridCells.Fixed(1),
+ modifier = Modifier.size(size),
+ state = lazyStaggeredGridState,
+ reverseLayout = it.reverseLayout,
+ content = content
+ )
+
+ else -> unsupportedDirection()
+ }
}
}
}
@@ -682,7 +756,7 @@
private val visibleItems: List<Int>
get() = lazyStaggeredGridState.layoutInfo.visibleItemsInfo.map { it.index }
- private fun expectedExtraItemsBeforeVisibleBounds() = when (beyondBoundsLayoutDirection) {
+ private fun Param.expectedExtraItemsBeforeVisibleBounds() = when (beyondBoundsLayoutDirection) {
Right -> if (layoutDirection == Ltr) reverseLayout else !reverseLayout
Left -> if (layoutDirection == Ltr) !reverseLayout else reverseLayout
Above -> !reverseLayout
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt
index 52ea19d..effaf84 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/SelectableTest.kt
@@ -18,6 +18,7 @@
import android.os.Build.VERSION.SDK_INT
import androidx.compose.foundation.TapIndicationDelay
+import androidx.compose.foundation.TestIndication
import androidx.compose.foundation.TestIndicationNodeFactory
import androidx.compose.foundation.interaction.FocusInteraction
import androidx.compose.foundation.interaction.HoverInteraction
@@ -36,6 +37,7 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertModifierIsPure
import androidx.compose.testutils.first
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -1191,4 +1193,113 @@
assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
}
}
+
+ @Test
+ fun composedOverload_nonEquality() {
+ val onClick = {}
+ val modifier1 = Modifier.selectable(selected = true, onClick = onClick)
+ val modifier2 = Modifier.selectable(selected = true, onClick = onClick)
+
+ // The composed overload can never compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun nullInteractionSourceNullIndication_equality() {
+ val onClick = {}
+ assertModifierIsPure { toggleInput ->
+ Modifier.selectable(
+ selected = toggleInput,
+ interactionSource = null,
+ indication = null,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nonNullInteractionSourceNullIndication_equality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ assertModifierIsPure { toggleInput ->
+ Modifier.selectable(
+ selected = toggleInput,
+ interactionSource = interactionSource,
+ indication = null,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onClick = {}
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.selectable(
+ selected = toggleInput,
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nullInteractionSourceNonNullIndication_nonEquality() {
+ val onClick = {}
+ val indication = TestIndication {}
+ val modifier1 = Modifier.selectable(
+ selected = true,
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+ val modifier2 = Modifier.selectable(
+ selected = true,
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun nonNullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.selectable(
+ selected = toggleInput,
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun nonNullInteractionSourceNonNullIndication_nonEquality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndication {}
+ val modifier1 = Modifier.selectable(
+ selected = true,
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+ val modifier2 = Modifier.selectable(
+ selected = true,
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt
index eb8c612..e95c2bd9 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/selection/ToggleableTest.kt
@@ -18,6 +18,7 @@
import android.os.Build.VERSION.SDK_INT
import androidx.compose.foundation.TapIndicationDelay
+import androidx.compose.foundation.TestIndication
import androidx.compose.foundation.TestIndicationNodeFactory
import androidx.compose.foundation.interaction.FocusInteraction
import androidx.compose.foundation.interaction.HoverInteraction
@@ -39,6 +40,7 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
+import androidx.compose.testutils.assertModifierIsPure
import androidx.compose.testutils.first
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -1410,7 +1412,7 @@
}
@Test
- fun triStateToggleableTest_noInteractionSource_lazilyCreated_pointerInput() {
+ fun triStateToggleable_noInteractionSource_lazilyCreated_pointerInput() {
var created = false
val state = ToggleableState(value = false)
lateinit var interactionSource: InteractionSource
@@ -1453,4 +1455,222 @@
assertThat(interactions.first()).isInstanceOf(PressInteraction.Press::class.java)
}
}
+
+ @Test
+ fun toggleable_composedOverload_nonEquality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ val modifier1 = Modifier.toggleable(value = true, onValueChange = onValueChange)
+ val modifier2 = Modifier.toggleable(value = true, onValueChange = onValueChange)
+
+ // The composed overload can never compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun toggleable_nullInteractionSourceNullIndication_equality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ assertModifierIsPure { toggleInput ->
+ Modifier.toggleable(
+ value = toggleInput,
+ interactionSource = null,
+ indication = null,
+ onValueChange = onValueChange
+ )
+ }
+ }
+
+ @Test
+ fun toggleable_nonNullInteractionSourceNullIndication_equality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ val interactionSource = MutableInteractionSource()
+ assertModifierIsPure { toggleInput ->
+ Modifier.toggleable(
+ value = toggleInput,
+ interactionSource = interactionSource,
+ indication = null,
+ onValueChange = onValueChange
+ )
+ }
+ }
+
+ @Test
+ fun toggleable_nullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.toggleable(
+ value = toggleInput,
+ interactionSource = null,
+ indication = indication,
+ onValueChange = onValueChange
+ )
+ }
+ }
+
+ @Test
+ fun toggleable_nullInteractionSourceNonNullIndication_nonEquality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ val indication = TestIndication {}
+ val modifier1 = Modifier.toggleable(
+ value = true,
+ interactionSource = null,
+ indication = indication,
+ onValueChange = onValueChange
+ )
+ val modifier2 = Modifier.toggleable(
+ value = true,
+ interactionSource = null,
+ indication = indication,
+ onValueChange = onValueChange
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun toggleable_nonNullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.toggleable(
+ value = toggleInput,
+ interactionSource = interactionSource,
+ indication = indication,
+ onValueChange = onValueChange
+ )
+ }
+ }
+
+ @Test
+ fun toggleable_nonNullInteractionSourceNonNullIndication_nonEquality() {
+ val onValueChange: (Boolean) -> Unit = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndication {}
+ val modifier1 = Modifier.toggleable(
+ value = true,
+ interactionSource = interactionSource,
+ indication = indication,
+ onValueChange = onValueChange
+ )
+ val modifier2 = Modifier.toggleable(
+ value = true,
+ interactionSource = interactionSource,
+ indication = indication,
+ onValueChange = onValueChange
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun triStateToggleable_composedOverload_nonEquality() {
+ val onClick = {}
+ val modifier1 = Modifier.triStateToggleable(state = ToggleableState.On, onClick = onClick)
+ val modifier2 = Modifier.triStateToggleable(state = ToggleableState.On, onClick = onClick)
+
+ // The composed overload can never compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun triStateToggleable_nullInteractionSourceNullIndication_equality() {
+ val onClick = {}
+ assertModifierIsPure { toggleInput ->
+ Modifier.triStateToggleable(
+ state = ToggleableState(toggleInput),
+ interactionSource = null,
+ indication = null,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun triStateToggleable_nonNullInteractionSourceNullIndication_equality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ assertModifierIsPure { toggleInput ->
+ Modifier.triStateToggleable(
+ state = ToggleableState(toggleInput),
+ interactionSource = interactionSource,
+ indication = null,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun triStateToggleable_nullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onClick = {}
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.triStateToggleable(
+ state = ToggleableState(toggleInput),
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun triStateToggleable_nullInteractionSourceNonNullIndication_nonEquality() {
+ val onClick = {}
+ val indication = TestIndication {}
+ val modifier1 = Modifier.triStateToggleable(
+ state = ToggleableState.On,
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+ val modifier2 = Modifier.triStateToggleable(
+ state = ToggleableState.On,
+ interactionSource = null,
+ indication = indication,
+ onClick = onClick
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
+
+ @Test
+ fun triStateToggleable_nonNullInteractionSourceNonNullIndicationNodeFactory_equality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndicationNodeFactory({}, { _, _ -> })
+ assertModifierIsPure { toggleInput ->
+ Modifier.triStateToggleable(
+ state = ToggleableState(toggleInput),
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+ }
+ }
+
+ @Test
+ fun triStateToggleable_nonNullInteractionSourceNonNullIndication_nonEquality() {
+ val onClick = {}
+ val interactionSource = MutableInteractionSource()
+ val indication = TestIndication {}
+ val modifier1 = Modifier.triStateToggleable(
+ state = ToggleableState.On,
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+ val modifier2 = Modifier.triStateToggleable(
+ state = ToggleableState.On,
+ interactionSource = interactionSource,
+ indication = indication,
+ onClick = onClick
+ )
+
+ // Indication requires composed, so cannot compare equal
+ assertThat(modifier1).isNotEqualTo(modifier2)
+ }
}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/BasicTextField2Test.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/BasicTextField2Test.kt
index 2c9d022..10548f9 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/BasicTextField2Test.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/BasicTextField2Test.kt
@@ -16,6 +16,7 @@
package androidx.compose.foundation.text.input
+import android.os.Build
import android.text.InputType
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
@@ -28,10 +29,12 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.BasicTextField2
import androidx.compose.foundation.text.KeyboardHelper
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.TEST_FONT_FAMILY
+import androidx.compose.foundation.text.computeSizeForDefaultText
import androidx.compose.foundation.text.input.TextFieldBuffer.ChangeList
import androidx.compose.foundation.text.input.internal.selection.FakeClipboardManager
import androidx.compose.foundation.text.selection.fetchTextLayoutResult
@@ -44,16 +47,20 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
+import androidx.compose.testutils.assertPixelColor
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.graphics.toPixelMap
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.LocalFontFamilyResolver
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.platform.WindowInfo
@@ -66,6 +73,7 @@
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.assertIsNotFocused
import androidx.compose.ui.test.assertTextEquals
+import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.onNodeWithTag
@@ -87,6 +95,7 @@
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -1408,6 +1417,104 @@
}
}
+ @Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ fun textField_textAlignCenter_defaultWidth() {
+ val fontSize = 50
+ val density = Density(1f, 1f)
+ val textStyle = TextStyle(
+ textAlign = TextAlign.Center,
+ color = Color.Black,
+ fontFamily = TEST_FONT_FAMILY,
+ fontSize = fontSize.sp
+ )
+ rule.setContent {
+ CompositionLocalProvider(LocalDensity provides density) {
+ BasicTextField2(
+ modifier = Modifier.testTag(Tag),
+ state = rememberTextFieldState("A"),
+ textStyle = textStyle,
+ lineLimits = TextFieldLineLimits.SingleLine
+ )
+ }
+ }
+
+ rule.waitForIdle()
+ rule.onNodeWithTag(Tag).captureToImage().assertHorizontallySymmetrical(fontSize)
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ fun textField_textAlignCenter_widthSmallerThanDefaultWidth() {
+ val fontSize = 50
+ val density = Density(1f, 1f)
+ val textStyle = TextStyle(
+ textAlign = TextAlign.Center,
+ color = Color.Black,
+ fontFamily = TEST_FONT_FAMILY,
+ fontSize = fontSize.sp
+ )
+ rule.setContent {
+ val fontFamilyResolver = LocalFontFamilyResolver.current
+ val defaultWidth = computeSizeForDefaultText(
+ style = textStyle,
+ density = density,
+ fontFamilyResolver = fontFamilyResolver,
+ maxLines = 1
+ ).width
+
+ CompositionLocalProvider(LocalDensity provides density) {
+ BasicTextField2(
+ modifier = Modifier
+ .testTag(Tag)
+ .width(defaultWidth.dp / 2),
+ state = rememberTextFieldState("A"),
+ textStyle = textStyle,
+ lineLimits = TextFieldLineLimits.SingleLine
+ )
+ }
+ }
+
+ rule.waitForIdle()
+ rule.onNodeWithTag(Tag).captureToImage().assertHorizontallySymmetrical(fontSize)
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ fun textField_textAlignCenter_widthLargerThanDefaultWidth() {
+ val fontSize = 50
+ val density = Density(1f, 1f)
+ val textStyle = TextStyle(
+ textAlign = TextAlign.Center,
+ color = Color.Black,
+ fontFamily = TEST_FONT_FAMILY,
+ fontSize = fontSize.sp
+ )
+ rule.setContent {
+ val fontFamilyResolver = LocalFontFamilyResolver.current
+ val defaultWidth = computeSizeForDefaultText(
+ style = textStyle,
+ density = density,
+ fontFamilyResolver = fontFamilyResolver,
+ maxLines = 1
+ ).width
+
+ CompositionLocalProvider(LocalDensity provides density) {
+ BasicTextField2(
+ modifier = Modifier
+ .testTag(Tag)
+ .width(defaultWidth.dp * 2),
+ state = rememberTextFieldState("A"),
+ textStyle = textStyle,
+ lineLimits = TextFieldLineLimits.SingleLine
+ )
+ }
+ }
+
+ rule.waitForIdle()
+ rule.onNodeWithTag(Tag).captureToImage().assertHorizontallySymmetrical(fontSize)
+ }
+
private fun requestFocus(tag: String) =
rule.onNodeWithTag(tag).requestFocus()
@@ -1443,3 +1550,17 @@
}
}
}
+
+/**
+ * Checks whether the given image is horizontally symmetrical where a region that has the width
+ * of [excludedWidth] around the center is excluded.
+ */
+private fun ImageBitmap.assertHorizontallySymmetrical(excludedWidth: Int) {
+ val pixel = toPixelMap()
+ for (y in 0 until height) {
+ for (x in 0 until (width - excludedWidth) / 2) {
+ val leftPixel = pixel[x, y]
+ pixel.assertPixelColor(leftPixel, width - 1 - x, y)
+ }
+ }
+}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/TextFieldCursorTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/TextFieldCursorTest.kt
index 34a5847..fbb0eab 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/TextFieldCursorTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/TextFieldCursorTest.kt
@@ -754,7 +754,6 @@
.assertDoesNotContainColor(cursorColor)
}
- @Ignore("b/305799612")
@Test
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
fun focusedTextField_resumeBlinking_whenWindowRegainsFocus() {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/undo/BasicTextField2UndoTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/undo/BasicTextField2UndoTest.kt
index ae68446..cdb3d02 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/undo/BasicTextField2UndoTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/input/internal/undo/BasicTextField2UndoTest.kt
@@ -40,6 +40,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -249,6 +250,7 @@
assertThat(state.undoState.canUndo).isFalse()
}
+ @Ignore("b/323405120")
@Test
fun clearHistory_removesAllUndoAndRedo() {
val state = TextFieldState()
@@ -285,6 +287,7 @@
}
}
+ @Ignore("b/323344335")
@Test
fun paste_neverMerges() {
val state = TextFieldState()
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/ToCharArray.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/ToCharArray.android.kt
index 968f6ec..700bbca 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/ToCharArray.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/ToCharArray.android.kt
@@ -16,7 +16,6 @@
package androidx.compose.foundation.text.input.internal
-import android.text.TextUtils
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.text.input.TextFieldCharSequence
import androidx.compose.foundation.text.input.toCharArray
@@ -31,6 +30,9 @@
if (this is TextFieldCharSequence) {
toCharArray(destination, destinationOffset, startIndex, endIndex)
} else {
- TextUtils.getChars(this, startIndex, endIndex, destination, destinationOffset)
+ var dstIndex = destinationOffset
+ for (srcIndex in startIndex until endIndex) {
+ destination[dstIndex++] = this[srcIndex]
+ }
}
}
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/BasicTextPaparazziTest.kt b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/BasicTextPaparazziTest.kt
deleted file mode 100644
index c65c711..0000000
--- a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/BasicTextPaparazziTest.kt
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.foundation.text
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.SideEffect
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalLayoutDirection
-import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.dp
-import androidx.constraintlayout.compose.ConstraintLayout
-import androidx.constraintlayout.compose.Dimension
-import androidx.testutils.paparazzi.androidxPaparazzi
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class BasicTextPaparazziTest {
- @get:Rule
- val paparazzi = androidxPaparazzi()
-
- @Test
- fun colorChangingState_changesColor() {
- paparazzi.snapshot {
- var color = remember { mutableStateOf(Color.Red) }
- BasicText(
- "ABCD",
- color = { color.value }
- )
- SideEffect {
- color.value = Color.Yellow
- }
- }
- }
-
- @Test
- fun colorChangingState_changesColor_annotatedString() {
- paparazzi.snapshot {
- var color = remember { mutableStateOf(Color.Red) }
- BasicText(
- AnnotatedString("ABCD"),
- color = { color.value }
- )
- SideEffect {
- color.value = Color.Yellow
- }
- }
- }
-
- @Test
- fun overflowEllipsis_doesEllipsis_whenInPreferredWrapContent() {
- paparazzi.snapshot {
- // b/275369323
- ConstraintLayout(modifier = Modifier
- .width(100.dp)
- .background(Color.White)
- .padding(8.dp)) {
- val (thumbnail, textBox, actionButton) = createRefs()
- Box(modifier = Modifier
- .background(Color.Green)
- .constrainAs(thumbnail) {
- top.linkTo(parent.top)
- start.linkTo(parent.start)
- bottom.linkTo(parent.bottom)
- }
- .size(28.dp)
- )
- // Text region
- Column(
- modifier = Modifier
- .constrainAs(textBox) {
- top.linkTo(parent.top)
- bottom.linkTo(parent.bottom)
- start.linkTo(thumbnail.end)
- end.linkTo(actionButton.start)
- width = Dimension.preferredWrapContent
- },
- ) {
- BasicText(
- text = "ASome very long text that is sure to clip in this layout",
- maxLines = 1,
- overflow = TextOverflow.Ellipsis
- )
- }
- Box(modifier = Modifier
- .constrainAs(actionButton) {
- top.linkTo(parent.top)
- bottom.linkTo(parent.bottom)
- end.linkTo(parent.end)
- }
- .background(Color.Blue.copy(alpha = 0.5f))
- .size(28.dp)
- )
- }
- }
- }
-
- @Test
- fun RtlAppliedCorrectly_inConstraintLayout_withWrapContentText() {
- // b/275369323
- paparazzi.snapshot {
- CompositionLocalProvider(
- LocalLayoutDirection provides LayoutDirection.Rtl
- ) {
- ConstraintLayout(
- Modifier
- .fillMaxWidth()
- .background(Color.Green)) {
- val (title, progressBar, expander) = createRefs()
- BasicText(
- text = "Locale-aware Text",
- modifier = Modifier
- .constrainAs(title) {
- top.linkTo(parent.top)
- start.linkTo(parent.start)
- end.linkTo(expander.start)
- width = Dimension.fillToConstraints
- }
- .border(2.dp, Color.Red)
- )
- Box(
- modifier = Modifier
- .constrainAs(progressBar) {
- top.linkTo(title.bottom)
- start.linkTo(parent.start)
- end.linkTo(expander.start)
- width = Dimension.fillToConstraints
- height = Dimension.value(10.dp)
- }
- .background(Color.Yellow)
- )
- // expander image button
- Box(modifier = Modifier
- .constrainAs(expander) {
- top.linkTo(parent.top)
- start.linkTo(progressBar.end)
- end.linkTo(parent.end)
- width = Dimension.value(28.dp)
- height = Dimension.value(28.dp)
- }
- .background(Color.Cyan)
- )
- }
- }
- }
- }
-}
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
new file mode 100644
index 0000000..58920e6
--- /dev/null
+++ b/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.text.input.internal
+
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(JUnit4::class)
+class CursorAnimationStateTest {
+
+ private val animationState = CursorAnimationState()
+
+ @Test
+ fun alphaNotAnimatingInitially() = runTest {
+ assertNotAnimating()
+ }
+
+ @Test
+ fun snapToVisibleAndAnimate_animatesAlpha() = runTest {
+ val job = launch {
+ animationState.snapToVisibleAndAnimate()
+ }
+
+ // Should start immediately.
+ assertThat(animationState.cursorAlpha).isEqualTo(0f)
+ runCurrent()
+
+ // Then let's verify a few blinks…
+ assertThat(animationState.cursorAlpha).isEqualTo(1f)
+ testScheduler.advanceTimeBy(500)
+ assertThat(animationState.cursorAlpha).isEqualTo(1f)
+ testScheduler.advanceTimeBy(500)
+ assertThat(animationState.cursorAlpha).isEqualTo(0f)
+ testScheduler.advanceTimeBy(500)
+ assertThat(animationState.cursorAlpha).isEqualTo(1f)
+
+ job.cancel()
+ }
+
+ @Test
+ fun snapToVisibleAndAnimate_suspendsWhileAnimating() = runTest {
+ val job = launch(start = CoroutineStart.UNDISPATCHED) {
+ animationState.snapToVisibleAndAnimate()
+ }
+
+ // Advance a few blinks.
+ repeat(10) {
+ testScheduler.advanceTimeBy(500)
+ assertThat(job.isActive).isTrue()
+ }
+
+ job.cancel()
+ }
+
+ @Test
+ fun snapToVisibleAndAnimate_stopsAnimating_whenCancelledImmediately() = runTest {
+ val job = launch(start = CoroutineStart.UNDISPATCHED) {
+ animationState.snapToVisibleAndAnimate()
+ }
+ job.cancel()
+
+ assertNotAnimating()
+ assertThat(job.isActive).isFalse()
+ }
+
+ @Test
+ fun snapToVisibleAndAnimate_stopsAnimating_whenCancelledAsync() = runTest {
+ val job = launch {
+ animationState.snapToVisibleAndAnimate()
+ }
+ job.cancel()
+
+ assertNotAnimating()
+ assertThat(job.isActive).isFalse()
+ }
+
+ @Test
+ fun snapToVisibleAndAnimate_stopsAnimating_whenCancelledAfterAWhile() = runTest {
+ val job = launch(start = CoroutineStart.UNDISPATCHED) {
+ animationState.snapToVisibleAndAnimate()
+ }
+
+ // Advance a few blinks…
+ repeat(10) {
+ testScheduler.advanceTimeBy(500)
+ }
+ job.cancel()
+
+ assertNotAnimating()
+ }
+
+ @Test
+ fun cancelAndHide_stopsAnimating_immediately() = runTest {
+ val job = launch(start = CoroutineStart.UNDISPATCHED) {
+ animationState.snapToVisibleAndAnimate()
+ }
+ animationState.cancelAndHide()
+
+ assertNotAnimating()
+ assertThat(job.isActive).isFalse()
+ }
+
+ @Test
+ fun cancelAndHide_beforeStart_doesntBlockAnimation() = runTest {
+ animationState.cancelAndHide()
+ val job = launch {
+ animationState.snapToVisibleAndAnimate()
+ }
+
+ runCurrent()
+ assertThat(animationState.cursorAlpha).isEqualTo(1f)
+
+ job.cancel()
+ }
+
+ @Test
+ fun cancelAndHide_stopsAnimating_afterAWhile() = runTest {
+ val job = launch(start = CoroutineStart.UNDISPATCHED) {
+ animationState.snapToVisibleAndAnimate()
+ }
+
+ // Advance a few blinks…
+ repeat(10) {
+ testScheduler.advanceTimeBy(500)
+ }
+ animationState.cancelAndHide()
+
+ assertNotAnimating()
+ assertThat(job.isActive).isFalse()
+ }
+
+ private fun TestScope.assertNotAnimating() {
+ // Allow the cancellation to process.
+ advanceUntilIdle()
+
+ // Verify a few blinks.
+ repeat(10) {
+ assertThat(animationState.cursorAlpha).isEqualTo(0f)
+ testScheduler.advanceTimeBy(490)
+ }
+ }
+}
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 3666e2e..1fabc9c 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
@@ -497,7 +497,6 @@
)
}
- // Defined in the factory functions with inspectable
override fun InspectorInfo.inspectableProperties() {
name = "clickable"
properties["enabled"] = enabled
@@ -573,7 +572,6 @@
)
}
- // Defined in the factory functions with inspectable
override fun InspectorInfo.inspectableProperties() {
name = "combinedClickable"
properties["indicationNodeFactory"] = indicationNodeFactory
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 59c5297..cd801d5 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
@@ -65,6 +65,7 @@
* @param interactionSource [MutableInteractionSource] that will be used to emit
* [FocusInteraction.Focus] when this element is being focused.
*/
+@Stable
fun Modifier.focusable(
enabled: Boolean = true,
interactionSource: MutableInteractionSource? = null,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Hoverable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Hoverable.kt
index c0180eb..00adcf2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Hoverable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Hoverable.kt
@@ -18,6 +18,7 @@
import androidx.compose.foundation.interaction.HoverInteraction
import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.PointerEvent
import androidx.compose.ui.input.pointer.PointerEventPass
@@ -37,6 +38,7 @@
* [HoverInteraction.Enter] when this element is being hovered.
* @param enabled Controls the enabled state. When `false`, hover events will be ignored.
*/
+@Stable
fun Modifier.hoverable(
interactionSource: MutableInteractionSource,
enabled: Boolean = true
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
index 4fda9bf..68272fc 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldCursor.kt
@@ -16,10 +16,10 @@
package androidx.compose.foundation.text
-import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
+import androidx.compose.foundation.text.input.internal.CursorAnimationState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
@@ -31,11 +31,10 @@
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.isUnspecified
+import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.util.fastCoerceIn
-import kotlinx.coroutines.withContext
internal fun Modifier.cursor(
state: LegacyTextFieldState,
@@ -44,21 +43,20 @@
cursorBrush: Brush,
enabled: Boolean
) = if (enabled) composed {
- val cursorAlpha = remember { Animatable(1f) }
+ val cursorAnimation = remember { CursorAnimationState() }
+ // Don't bother animating the cursor if it wouldn't draw any pixels.
val isBrushSpecified = !(cursorBrush is SolidColor && cursorBrush.value.isUnspecified)
- if (state.hasFocus && value.selection.collapsed && isBrushSpecified) {
+ // Only animate the cursor when its window is actually focused. This also disables the cursor
+ // animation when the screen is off.
+ // TODO confirm screen-off behavior.
+ val isWindowFocused = LocalWindowInfo.current.isWindowFocused
+ if (isWindowFocused && state.hasFocus && value.selection.collapsed && isBrushSpecified) {
LaunchedEffect(value.annotatedString, value.selection) {
- // Animate the cursor even when animations are disabled by the system.
- withContext(FixedMotionDurationScale) {
- // ensure that the value is always 1f _this_ frame by calling snapTo
- cursorAlpha.snapTo(1f)
- // then start the cursor blinking on animation clock (500ms on to start)
- cursorAlpha.animateTo(0f, cursorAnimationSpec)
- }
+ cursorAnimation.snapToVisibleAndAnimate()
}
drawWithContent {
this.drawContent()
- val cursorAlphaValue = cursorAlpha.value.fastCoerceIn(0f, 1f)
+ val cursorAlphaValue = cursorAnimation.cursorAlpha
if (cursorAlphaValue != 0f) {
val transformedOffset = offsetMapping
.originalToTransformed(value.selection.start)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt
new file mode 100644
index 0000000..e9898ab
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationState.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.text.input.internal
+
+import androidx.compose.foundation.AtomicReference
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.setValue
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancelAndJoin
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+/**
+ * Holds the state of the animation that blinks the cursor.
+ *
+ * We can't use the Compose Animation APIs because they busy-loop on delays, and this animation
+ * spends most of its time delayed so that's a ton of wasted frames. Pure coroutine delays, however,
+ * will not cause any work to be done until the delay is over.
+ */
+internal class CursorAnimationState {
+
+ private var animationJob = AtomicReference<Job?>(null)
+
+ /**
+ * The alpha value that should be used to draw the cursor.
+ * Will always be in the range [0, 1].
+ */
+ var cursorAlpha by mutableFloatStateOf(0f)
+ private set
+
+ /**
+ * Immediately shows the cursor (sets [cursorAlpha] to 1f) and starts blinking it on and off
+ * every 500ms. If a previous animation was running, it will be cancelled before the new one
+ * starts.
+ *
+ * Won't return until the animation cancelled via [cancelAndHide] or this coroutine's [Job] is
+ * cancelled. In both cases, the cursor will always end up hidden.
+ */
+ suspend fun snapToVisibleAndAnimate() {
+ coroutineScope {
+ // Can't do a single atomic update because we need to get the old value before launching
+ // the new coroutine. So we set to null first, and then launch only if still null (i.e.
+ // no other caller beat us to starting a new animation).
+ val oldJob = animationJob.getAndSet(null)
+
+ // Even though we're launching a new coroutine, because of structured concurrency, the
+ // restart function won't return until the animation is finished, and cancelling the
+ // calling coroutine will cancel the animation.
+ animationJob.compareAndSet(null, launch {
+ // Join the old job after cancelling to ensure it finishes its finally block before
+ // we start changing the cursor alpha, so we don't end up interleaving alpha
+ // updates.
+ oldJob?.cancelAndJoin()
+
+ // Start the new animation and run until cancelled.
+ try {
+ while (true) {
+ cursorAlpha = 1f
+ // Ignore MotionDurationScale – the cursor should blink even when animations
+ // are disabled by the system.
+ delay(500)
+ cursorAlpha = 0f
+ delay(500)
+ }
+ } finally {
+ // Hide cursor when the animation is cancelled.
+ cursorAlpha = 0f
+ }
+ })
+ }
+ }
+
+ /**
+ * Immediately cancels the cursor animation and hides the cursor (sets [cursorAlpha] to 0f).
+ */
+ fun cancelAndHide() {
+ val job = animationJob.getAndSet(null)
+ job?.cancel()
+ }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt
index 8c8b7cd..48d9bbd 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/input/internal/TextFieldCoreModifier.kt
@@ -16,10 +16,6 @@
package androidx.compose.foundation.text.input.internal
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.AnimationSpec
-import androidx.compose.animation.core.infiniteRepeatable
-import androidx.compose.animation.core.keyframes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.gestures.Orientation
@@ -29,7 +25,6 @@
import androidx.compose.foundation.text.input.internal.selection.textFieldMagnifierNode
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
import androidx.compose.runtime.snapshotFlow
-import androidx.compose.ui.MotionDurationScale
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
@@ -52,6 +47,7 @@
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.node.invalidateMeasurement
import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextPainter
@@ -60,7 +56,6 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.util.fastCoerceIn
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.min
@@ -69,7 +64,6 @@
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
/**
* Modifier element for the core functionality of [BasicTextField2] that is passed as inner
@@ -146,7 +140,7 @@
* another half a second when TextField is focused and editable. Initial value should be 0f
* so that when cursor needs to be drawn for the first time, change to 1f invalidates draw.
*/
- private val cursorAlpha = Animatable(0f)
+ private val cursorAnimation = CursorAnimationState()
/**
* Whether to show cursor at all when TextField has focus. This depends on enabled, read only,
@@ -221,7 +215,7 @@
if (!showCursor) {
changeObserverJob?.cancel()
changeObserverJob = null
- coroutineScope.launch { cursorAlpha.snapTo(0f) }
+ cursorAnimation.cancelAndHide()
} else if (!wasFocused ||
previousTextFieldState != textFieldState ||
!previousShowCursor
@@ -229,15 +223,17 @@
// this node is writeable, focused and gained that focus just now.
// start the state value observation
changeObserverJob = coroutineScope.launch {
- // Animate the cursor even when animations are disabled by the system.
- withContext(FixedMotionDurationScale) {
- snapshotFlow { textFieldState.visualText }
- .collectLatest {
- // ensure that the value is always 1f _this_ frame by calling snapTo
- cursorAlpha.snapTo(1f)
- // then start the cursor blinking on animation clock (500ms on to start)
- cursorAlpha.animateTo(0f, cursorAnimationSpec)
- }
+ snapshotFlow {
+ // Read the text state, so the animation restarts when the text or cursor
+ // position change.
+ textFieldState.visualText
+ // Only animate the cursor when its window is actually focused. This also
+ // disables the cursor animation when the screen is off.
+ currentValueOf(LocalWindowInfo).isWindowFocused
+ }.collectLatest { isWindowFocused ->
+ if (isWindowFocused) {
+ cursorAnimation.snapToVisibleAndAnimate()
+ }
}
}
}
@@ -311,18 +307,8 @@
measurable: Measurable,
constraints: Constraints
): MeasureResult {
- // If the maxIntrinsicWidth of the children is already smaller than the constraint, pass
- // the original constraints so that the children has more information to determine its
- // size.
- val maxIntrinsicWidth = measurable.maxIntrinsicWidth(constraints.maxHeight)
-
// remove any width constraints for TextField since it'll be able to scroll horizontally.
- val childConstraints = if (maxIntrinsicWidth < constraints.maxWidth) {
- constraints
- } else {
- constraints.copy(maxWidth = Constraints.Infinity)
- }
- val placeable = measurable.measure(childConstraints)
+ val placeable = measurable.measure(constraints.copy(maxWidth = Constraints.Infinity))
val width = min(placeable.width, constraints.maxWidth)
return layout(width, placeable.height) {
@@ -453,10 +439,7 @@
// this call will respect the earlier set maxValue
// no need to coerce again.
// prefer to use immediate dispatch instead of suspending scroll calls
- coroutineScope.launch(
- DisabledMotionDurationScale,
- start = CoroutineStart.UNDISPATCHED
- ) {
+ coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {
scrollState.scrollBy(offsetDifference.roundToNext())
// make sure to use the cursor rect from text layout since bringIntoView does its
// own checks for RTL layouts.
@@ -498,12 +481,9 @@
private fun DrawScope.drawCursor() {
// Only draw cursor if it can be shown and its alpha is higher than 0f
// Alpha is checked before showCursor purposefully to make sure that we read
- // cursorAlpha.value in draw phase. So, when the alpha value changes, draw phase
- // invalidates.
- if (cursorAlpha.value <= 0f || !showCursor) return
-
- val cursorAlphaValue = cursorAlpha.value.fastCoerceIn(0f, 1f)
- if (cursorAlphaValue == 0f) return
+ // cursorAlpha in draw phase. So, when the alpha value changes, draw phase invalidates.
+ val cursorAlphaValue = cursorAnimation.cursorAlpha
+ if (cursorAlphaValue == 0f || !showCursor) return
val cursorRect = textFieldSelectionState.cursorRect
@@ -526,16 +506,6 @@
}
}
-private val cursorAnimationSpec: AnimationSpec<Float> = infiniteRepeatable(
- animation = keyframes {
- durationMillis = 1000
- 1f at 0
- 1f at 499
- 0f at 500
- 0f at 999
- }
-)
-
private val DefaultCursorThickness = 2.dp
/**
@@ -544,16 +514,6 @@
private val Brush.isSpecified: Boolean
get() = !(this is SolidColor && this.value.isUnspecified)
-private object FixedMotionDurationScale : MotionDurationScale {
- override val scaleFactor: Float
- get() = 1f
-}
-
-private object DisabledMotionDurationScale : MotionDurationScale {
- override val scaleFactor: Float
- get() = 0f
-}
-
/**
* Converts cursorRect in text layout coordinates to scroller coordinates by adding the default
* cursor thickness and calculating the relative positioning caused by the layout direction.
diff --git a/compose/material/material/build.gradle b/compose/material/material/build.gradle
index 7234f90..21f35fb2 100644
--- a/compose/material/material/build.gradle
+++ b/compose/material/material/build.gradle
@@ -28,7 +28,6 @@
id("AndroidXPlugin")
id("com.android.library")
id("AndroidXComposePlugin")
- id("AndroidXPaparazziPlugin")
}
androidXMultiplatform {
@@ -49,6 +48,7 @@
api("androidx.compose.ui:ui:1.6.0")
api("androidx.compose.ui:ui-text:1.6.0")
+ implementation(project(":compose:animation:animation-core"))
implementation("androidx.compose.animation:animation:1.6.0")
implementation("androidx.compose.foundation:foundation-layout:1.6.0")
implementation("androidx.compose.ui:ui-util:1.6.0")
diff --git a/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/ButtonPaparazziScreenshotTest.kt b/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/ButtonPaparazziScreenshotTest.kt
deleted file mode 100644
index 1aec7be..0000000
--- a/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/ButtonPaparazziScreenshotTest.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.material
-
-import androidx.testutils.paparazzi.androidxPaparazzi
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class ButtonPaparazziScreenshotTest {
- @get:Rule
- val paparazzi = androidxPaparazzi()
-
- @Test
- fun default_button() {
- paparazzi.snapshot {
- MaterialTheme {
- Surface {
- Button(onClick = { }) {
- Text("Button")
- }
- }
- }
- }
- }
-}
diff --git a/compose/material3/material3-adaptive/OWNERS b/compose/material3/adaptive/OWNERS
similarity index 100%
rename from compose/material3/material3-adaptive/OWNERS
rename to compose/material3/adaptive/OWNERS
diff --git a/compose/material3/adaptive/adaptive-layout/api/current.txt b/compose/material3/adaptive/adaptive-layout/api/current.txt
new file mode 100644
index 0000000..34e7c93
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-layout/api/current.txt
@@ -0,0 +1,173 @@
+// Signature format: 4.0
+package androidx.compose.material3.adaptive.layout {
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface AdaptStrategy {
+ method public String adapt();
+ field public static final androidx.compose.material3.adaptive.layout.AdaptStrategy.Companion Companion;
+ }
+
+ public static final class AdaptStrategy.Companion {
+ method public androidx.compose.material3.adaptive.layout.AdaptStrategy getHide();
+ property public final androidx.compose.material3.adaptive.layout.AdaptStrategy Hide;
+ }
+
+ @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class HingePolicy {
+ field public static final androidx.compose.material3.adaptive.layout.HingePolicy.Companion Companion;
+ }
+
+ public static final class HingePolicy.Companion {
+ method public int getAlwaysAvoid();
+ method public int getAvoidOccluding();
+ method public int getAvoidSeparating();
+ method public int getNeverAvoid();
+ property public final int AlwaysAvoid;
+ property public final int AvoidOccluding;
+ property public final int AvoidSeparating;
+ property public final int NeverAvoid;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldDefaults {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.layout.AdaptStrategy detailPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy listPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy extraPaneAdaptStrategy);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+ property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+ field public static final androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldDefaults INSTANCE;
+ }
+
+ public final class ListDetailPaneScaffoldKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void ListDetailPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> listPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> detailPane);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldRole {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getDetail();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getExtra();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getList();
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Detail;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Extra;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole List;
+ field public static final androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole INSTANCE;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedValue {
+ field public static final androidx.compose.material3.adaptive.layout.PaneAdaptedValue.Companion Companion;
+ }
+
+ public static final class PaneAdaptedValue.Companion {
+ method public String getExpanded();
+ method public String getHidden();
+ property public final String Expanded;
+ property public final String Hidden;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class PaneScaffoldDirective {
+ ctor public PaneScaffoldDirective(androidx.compose.foundation.layout.PaddingValues contentPadding, int maxHorizontalPartitions, float horizontalPartitionSpacerSize, int maxVerticalPartitions, float verticalPartitionSpacerSize, java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds);
+ method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+ method public java.util.List<androidx.compose.ui.geometry.Rect> getExcludedBounds();
+ method public float getHorizontalPartitionSpacerSize();
+ method public int getMaxHorizontalPartitions();
+ method public int getMaxVerticalPartitions();
+ method public float getVerticalPartitionSpacerSize();
+ property public final androidx.compose.foundation.layout.PaddingValues contentPadding;
+ property public final java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds;
+ property public final float horizontalPartitionSpacerSize;
+ property public final int maxHorizontalPartitions;
+ property public final int maxVerticalPartitions;
+ property public final float verticalPartitionSpacerSize;
+ }
+
+ public final class PaneScaffoldDirectiveKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.PaneScaffoldDirective calculateDensePaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.PaneScaffoldDirective calculateStandardPaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface PaneScaffoldScope {
+ method public androidx.compose.ui.Modifier preferredWidth(androidx.compose.ui.Modifier, float width);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldDefaults {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.layout.AdaptStrategy mainPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy supportingPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy extraPaneAdaptStrategy);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+ property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+ field public static final androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldDefaults INSTANCE;
+ }
+
+ public final class SupportingPaneScaffoldKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void SupportingPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> supportingPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> mainPane);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldRole {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getExtra();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getMain();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getSupporting();
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Extra;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Main;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Supporting;
+ field public static final androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole INSTANCE;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldAdaptStrategies {
+ ctor public ThreePaneScaffoldAdaptStrategies(androidx.compose.material3.adaptive.layout.AdaptStrategy primaryPaneAdaptStrategy, androidx.compose.material3.adaptive.layout.AdaptStrategy secondaryPaneAdaptStrategy, androidx.compose.material3.adaptive.layout.AdaptStrategy tertiaryPaneAdaptStrategy);
+ method public operator androidx.compose.material3.adaptive.layout.AdaptStrategy get(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole role);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldDestinationItem<T> {
+ ctor public ThreePaneScaffoldDestinationItem(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole pane, optional T? content);
+ method public T? getContent();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getPane();
+ property public final T? content;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole pane;
+ }
+
+ public final class ThreePaneScaffoldKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void AnimatedPane(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope, androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> content);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum ThreePaneScaffoldRole {
+ method public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole[] values();
+ enum_constant public static final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Primary;
+ enum_constant public static final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Secondary;
+ enum_constant public static final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Tertiary;
+ }
+
+ public interface ThreePaneScaffoldScope extends androidx.compose.material3.adaptive.layout.PaneScaffoldScope {
+ method public String getAnimationToolingLabel();
+ method public androidx.compose.animation.EnterTransition getEnterTransition();
+ method public androidx.compose.animation.ExitTransition getExitTransition();
+ method public String getPaneAdaptedValue();
+ method public androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? getPositionAnimationSpec();
+ property public abstract String animationToolingLabel;
+ property public abstract androidx.compose.animation.EnterTransition enterTransition;
+ property public abstract androidx.compose.animation.ExitTransition exitTransition;
+ property public abstract String paneAdaptedValue;
+ property public abstract androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? positionAnimationSpec;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldState {
+ method public androidx.compose.material3.adaptive.layout.PaneScaffoldDirective getScaffoldDirective();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue getScaffoldValue();
+ property public abstract androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective;
+ property public abstract androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue scaffoldValue;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class ThreePaneScaffoldValue {
+ ctor public ThreePaneScaffoldValue(String primary, String secondary, String tertiary);
+ method public operator String get(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole role);
+ method public String getPrimary();
+ method public String getSecondary();
+ method public String getTertiary();
+ property public final String primary;
+ property public final String secondary;
+ property public final String tertiary;
+ }
+
+ public final class ThreePaneScaffoldValueKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>? currentDestination);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>> destinationHistory);
+ }
+
+}
+
diff --git a/compose/material3/material3-adaptive/api/res-current.txt b/compose/material3/adaptive/adaptive-layout/api/res-current.txt
similarity index 100%
copy from compose/material3/material3-adaptive/api/res-current.txt
copy to compose/material3/adaptive/adaptive-layout/api/res-current.txt
diff --git a/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt b/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt
new file mode 100644
index 0000000..34e7c93
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-layout/api/restricted_current.txt
@@ -0,0 +1,173 @@
+// Signature format: 4.0
+package androidx.compose.material3.adaptive.layout {
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface AdaptStrategy {
+ method public String adapt();
+ field public static final androidx.compose.material3.adaptive.layout.AdaptStrategy.Companion Companion;
+ }
+
+ public static final class AdaptStrategy.Companion {
+ method public androidx.compose.material3.adaptive.layout.AdaptStrategy getHide();
+ property public final androidx.compose.material3.adaptive.layout.AdaptStrategy Hide;
+ }
+
+ @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class HingePolicy {
+ field public static final androidx.compose.material3.adaptive.layout.HingePolicy.Companion Companion;
+ }
+
+ public static final class HingePolicy.Companion {
+ method public int getAlwaysAvoid();
+ method public int getAvoidOccluding();
+ method public int getAvoidSeparating();
+ method public int getNeverAvoid();
+ property public final int AlwaysAvoid;
+ property public final int AvoidOccluding;
+ property public final int AvoidSeparating;
+ property public final int NeverAvoid;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldDefaults {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.layout.AdaptStrategy detailPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy listPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy extraPaneAdaptStrategy);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+ property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+ field public static final androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldDefaults INSTANCE;
+ }
+
+ public final class ListDetailPaneScaffoldKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void ListDetailPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> listPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> detailPane);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldRole {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getDetail();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getExtra();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getList();
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Detail;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Extra;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole List;
+ field public static final androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole INSTANCE;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedValue {
+ field public static final androidx.compose.material3.adaptive.layout.PaneAdaptedValue.Companion Companion;
+ }
+
+ public static final class PaneAdaptedValue.Companion {
+ method public String getExpanded();
+ method public String getHidden();
+ property public final String Expanded;
+ property public final String Hidden;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class PaneScaffoldDirective {
+ ctor public PaneScaffoldDirective(androidx.compose.foundation.layout.PaddingValues contentPadding, int maxHorizontalPartitions, float horizontalPartitionSpacerSize, int maxVerticalPartitions, float verticalPartitionSpacerSize, java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds);
+ method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+ method public java.util.List<androidx.compose.ui.geometry.Rect> getExcludedBounds();
+ method public float getHorizontalPartitionSpacerSize();
+ method public int getMaxHorizontalPartitions();
+ method public int getMaxVerticalPartitions();
+ method public float getVerticalPartitionSpacerSize();
+ property public final androidx.compose.foundation.layout.PaddingValues contentPadding;
+ property public final java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds;
+ property public final float horizontalPartitionSpacerSize;
+ property public final int maxHorizontalPartitions;
+ property public final int maxVerticalPartitions;
+ property public final float verticalPartitionSpacerSize;
+ }
+
+ public final class PaneScaffoldDirectiveKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.PaneScaffoldDirective calculateDensePaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.PaneScaffoldDirective calculateStandardPaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface PaneScaffoldScope {
+ method public androidx.compose.ui.Modifier preferredWidth(androidx.compose.ui.Modifier, float width);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldDefaults {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.layout.AdaptStrategy mainPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy supportingPaneAdaptStrategy, optional androidx.compose.material3.adaptive.layout.AdaptStrategy extraPaneAdaptStrategy);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
+ property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
+ field public static final androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldDefaults INSTANCE;
+ }
+
+ public final class SupportingPaneScaffoldKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void SupportingPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> supportingPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> mainPane);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldRole {
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getExtra();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getMain();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getSupporting();
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Extra;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Main;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Supporting;
+ field public static final androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole INSTANCE;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldAdaptStrategies {
+ ctor public ThreePaneScaffoldAdaptStrategies(androidx.compose.material3.adaptive.layout.AdaptStrategy primaryPaneAdaptStrategy, androidx.compose.material3.adaptive.layout.AdaptStrategy secondaryPaneAdaptStrategy, androidx.compose.material3.adaptive.layout.AdaptStrategy tertiaryPaneAdaptStrategy);
+ method public operator androidx.compose.material3.adaptive.layout.AdaptStrategy get(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole role);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldDestinationItem<T> {
+ ctor public ThreePaneScaffoldDestinationItem(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole pane, optional T? content);
+ method public T? getContent();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole getPane();
+ property public final T? content;
+ property public final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole pane;
+ }
+
+ public final class ThreePaneScaffoldKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void AnimatedPane(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope, androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope,kotlin.Unit> content);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum ThreePaneScaffoldRole {
+ method public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole[] values();
+ enum_constant public static final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Primary;
+ enum_constant public static final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Secondary;
+ enum_constant public static final androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole Tertiary;
+ }
+
+ public interface ThreePaneScaffoldScope extends androidx.compose.material3.adaptive.layout.PaneScaffoldScope {
+ method public String getAnimationToolingLabel();
+ method public androidx.compose.animation.EnterTransition getEnterTransition();
+ method public androidx.compose.animation.ExitTransition getExitTransition();
+ method public String getPaneAdaptedValue();
+ method public androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? getPositionAnimationSpec();
+ property public abstract String animationToolingLabel;
+ property public abstract androidx.compose.animation.EnterTransition enterTransition;
+ property public abstract androidx.compose.animation.ExitTransition exitTransition;
+ property public abstract String paneAdaptedValue;
+ property public abstract androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? positionAnimationSpec;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldState {
+ method public androidx.compose.material3.adaptive.layout.PaneScaffoldDirective getScaffoldDirective();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue getScaffoldValue();
+ property public abstract androidx.compose.material3.adaptive.layout.PaneScaffoldDirective scaffoldDirective;
+ property public abstract androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue scaffoldValue;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class ThreePaneScaffoldValue {
+ ctor public ThreePaneScaffoldValue(String primary, String secondary, String tertiary);
+ method public operator String get(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole role);
+ method public String getPrimary();
+ method public String getSecondary();
+ method public String getTertiary();
+ property public final String primary;
+ property public final String secondary;
+ property public final String tertiary;
+ }
+
+ public final class ThreePaneScaffoldValueKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>? currentDestination);
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<?>> destinationHistory);
+ }
+
+}
+
diff --git a/compose/material3/material3-adaptive/build.gradle b/compose/material3/adaptive/adaptive-layout/build.gradle
similarity index 90%
copy from compose/material3/material3-adaptive/build.gradle
copy to compose/material3/adaptive/adaptive-layout/build.gradle
index cbd842e..ec87135 100644
--- a/compose/material3/material3-adaptive/build.gradle
+++ b/compose/material3/adaptive/adaptive-layout/build.gradle
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 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.
@@ -23,7 +23,6 @@
*/
import androidx.build.LibraryType
import androidx.build.PlatformIdentifier
-import androidx.build.Publish
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@@ -43,6 +42,7 @@
dependencies {
implementation(libs.kotlinStdlibCommon)
api("androidx.compose.foundation:foundation:1.6.0-rc01")
+ api(project(":compose:material3:adaptive:adaptive"))
implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
// TODO(conradchen): pin the depe when the change required is released to public
@@ -67,7 +67,6 @@
dependencies {
api("androidx.annotation:annotation:1.1.0")
api("androidx.annotation:annotation-experimental:1.4.0")
- implementation("androidx.window:window:1.2.0")
}
}
@@ -110,12 +109,11 @@
}
android {
- namespace "androidx.compose.material3.adaptive"
+ namespace "androidx.compose.material3.adaptive.layout"
}
androidx {
name = "Material Adaptive"
- mavenVersion = LibraryVersions.COMPOSE_MATERIAL3_ADAPTIVE
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2023"
description = "Compose Material Design Adaptive Library"
@@ -128,6 +126,6 @@
// Screenshot tests related setup
android {
sourceSets.androidTest.assets.srcDirs +=
- project.rootDir.absolutePath + "/../../golden/compose/material3/material3-adaptive"
- namespace "androidx.compose.material3.adaptive"
+ project.rootDir.absolutePath + "/../../golden/compose/material3/adaptive"
+ namespace "androidx.compose.material3.adaptive.layout"
}
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/GoldenCommon.kt b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/GoldenCommon.kt
similarity index 90%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/GoldenCommon.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/GoldenCommon.kt
index a693e3a..f16ff5e 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/GoldenCommon.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/GoldenCommon.kt
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
-internal const val GOLDEN_MATERIAL3_ADAPTIVE = "compose/material3/material3-adaptive"
+internal const val GOLDEN_MATERIAL3_ADAPTIVE = "compose/material3/adaptive"
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/LargeScreenTestUtils.kt b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/LargeScreenTestUtils.kt
similarity index 90%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/LargeScreenTestUtils.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/LargeScreenTestUtils.kt
index 8ed7c70..5dfa0175 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/LargeScreenTestUtils.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/LargeScreenTestUtils.kt
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffoldStateTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffoldStateTest.kt
similarity index 89%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffoldStateTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffoldStateTest.kt
index 01bd1f7..77df51f 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffoldStateTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffoldStateTest.kt
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -72,8 +73,10 @@
composeRule.setContent {
scaffoldState = calculateListDetailPaneScaffoldState(
scaffoldDirective = MockSinglePaneScaffoldDirective,
- currentDestination =
- ThreePaneScaffoldDestinationItem(ListDetailPaneScaffoldRole.Detail, null)
+ currentDestination = ThreePaneScaffoldDestinationItem(
+ ListDetailPaneScaffoldRole.Detail,
+ null
+ )
)
}
@@ -90,8 +93,10 @@
composeRule.setContent {
scaffoldState = calculateListDetailPaneScaffoldState(
scaffoldDirective = MockDualPaneScaffoldDirective,
- currentDestination =
- ThreePaneScaffoldDestinationItem(ListDetailPaneScaffoldRole.Extra, null)
+ currentDestination = ThreePaneScaffoldDestinationItem(
+ ListDetailPaneScaffoldRole.Extra,
+ null
+ )
)
}
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffoldStateTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/SupportingPaneScaffoldStateTest.kt
similarity index 89%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffoldStateTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/SupportingPaneScaffoldStateTest.kt
index 169ccb9..fc8bb82 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffoldStateTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/SupportingPaneScaffoldStateTest.kt
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -72,8 +73,10 @@
composeRule.setContent {
scaffoldState = calculateSupportingPaneScaffoldState(
scaffoldDirective = MockSinglePaneScaffoldDirective,
- currentDestination =
- ThreePaneScaffoldDestinationItem(SupportingPaneScaffoldRole.Supporting, null)
+ currentDestination = ThreePaneScaffoldDestinationItem(
+ SupportingPaneScaffoldRole.Supporting,
+ null
+ )
)
}
@@ -90,8 +93,10 @@
composeRule.setContent {
scaffoldState = calculateSupportingPaneScaffoldState(
scaffoldDirective = MockDualPaneScaffoldDirective,
- currentDestination =
- ThreePaneScaffoldDestinationItem(SupportingPaneScaffoldRole.Extra, null)
+ currentDestination = ThreePaneScaffoldDestinationItem(
+ SupportingPaneScaffoldRole.Extra,
+ null
+ )
)
}
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldScreenshotTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldScreenshotTest.kt
similarity index 96%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldScreenshotTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldScreenshotTest.kt
index 1659ae5..c707ab5 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldScreenshotTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldScreenshotTest.kt
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import android.os.Build
import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.test.captureToImage
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldTest.kt
similarity index 98%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldTest.kt
index f142449..57db5ac 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
@@ -24,6 +24,7 @@
import androidx.compose.foundation.layout.union
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/PaneScaffoldDirectiveTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt
similarity index 97%
rename from compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/PaneScaffoldDirectiveTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt
index f40a549..2813adb 100644
--- a/compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/PaneScaffoldDirectiveTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt
@@ -14,8 +14,12 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.HingeInfo
+import androidx.compose.material3.adaptive.Posture
+import androidx.compose.material3.adaptive.WindowAdaptiveInfo
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
diff --git a/compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/ThreePaneMotionTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneMotionTest.kt
similarity index 98%
rename from compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/ThreePaneMotionTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneMotionTest.kt
index f8d2333..cf50df31 100644
--- a/compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/ThreePaneMotionTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneMotionTest.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValueTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt
similarity index 97%
rename from compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValueTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt
index b2b2fba..48dbd86 100644
--- a/compose/material3/material3-adaptive/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValueTest.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptStrategy.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/AdaptStrategy.kt
similarity index 92%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptStrategy.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/AdaptStrategy.kt
index 550ffda..6f73836 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptStrategy.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/AdaptStrategy.kt
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
/**
* Provides the information about how the associated pane should be adapted if it cannot be
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AnimateBoundsModifier.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/AnimateBoundsModifier.kt
similarity index 98%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AnimateBoundsModifier.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/AnimateBoundsModifier.kt
index 43c39b7..0e97207 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AnimateBoundsModifier.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/AnimateBoundsModifier.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationVector
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffold.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt
similarity index 97%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffold.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt
index 690c11b..e6d9904 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffold.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedValue.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneAdaptedValue.kt
similarity index 90%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedValue.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneAdaptedValue.kt
index 5d21a80..54501b1 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedValue.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneAdaptedValue.kt
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
/**
* The adapted state of a pane. It gives clues to pane scaffolds about if a certain pane should be
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffold.kt
similarity index 96%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffold.kt
index a25f6b9..57f1ad7 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffold.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffold.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.ParentDataModifierNode
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffoldDirective.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirective.kt
similarity index 92%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffoldDirective.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirective.kt
index 272dffd..18bc602 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneScaffoldDirective.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirective.kt
@@ -14,9 +14,16 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.Posture
+import androidx.compose.material3.adaptive.WindowAdaptiveInfo
+import androidx.compose.material3.adaptive.allVerticalHingeBounds
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
+import androidx.compose.material3.adaptive.occludingVerticalHingeBounds
+import androidx.compose.material3.adaptive.separatingVerticalHingeBounds
import androidx.compose.runtime.Immutable
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.unit.Dp
@@ -25,7 +32,7 @@
/**
* Calculates the standard [PaneScaffoldDirective] from a given [WindowAdaptiveInfo]. Use this
- * method with [calculateWindowAdaptiveInfo] to acquire Material-recommended adaptive layout
+ * method with [currentWindowAdaptiveInfo] to acquire Material-recommended adaptive layout
* settings of the current activity window.
*
* See more details on the [Material design guideline site]
@@ -87,7 +94,7 @@
/**
* Calculates the dense-mode [PaneScaffoldDirective] from a given [WindowAdaptiveInfo]. Use this
- * method with [calculateWindowAdaptiveInfo] to acquire Material-recommended dense-mode adaptive
+ * method with [currentWindowAdaptiveInfo] to acquire Material-recommended dense-mode adaptive
* layout settings of the current activity window.
*
* See more details on the [Material design guideline site]
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffold.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/SupportingPaneScaffold.kt
similarity index 97%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffold.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/SupportingPaneScaffold.kt
index 6cc19e6..7764d64 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffold.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/SupportingPaneScaffold.kt
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffold.kt
similarity index 99%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffold.kt
index ecea8a9..d17b2c6 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffold.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffold.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
import androidx.annotation.VisibleForTesting
import androidx.compose.animation.AnimatedVisibility
@@ -28,6 +28,7 @@
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldAdaptStrategies.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldAdaptStrategies.kt
similarity index 94%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldAdaptStrategies.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldAdaptStrategies.kt
index b0f43b1..62fd21c 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldAdaptStrategies.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldAdaptStrategies.kt
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
/**
* The adaptation specs of [ThreePaneScaffold]. This class denotes how each pane of
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldDestinationItem.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldDestinationItem.kt
similarity index 73%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldDestinationItem.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldDestinationItem.kt
index 6ff7e00..797a08f 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldDestinationItem.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldDestinationItem.kt
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
-import androidx.compose.runtime.saveable.Saver
-import androidx.compose.runtime.saveable.listSaver
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
/**
* An item representing a navigation destination in a [ThreePaneScaffold].
@@ -31,19 +30,6 @@
val pane: ThreePaneScaffoldRole,
val content: T? = null,
) {
- companion object {
- internal fun <T> saver(): Saver<ThreePaneScaffoldDestinationItem<T>, Any> = listSaver(
- save = { listOf(it.pane, it.content) },
- restore = {
- @Suppress("UNCHECKED_CAST")
- ThreePaneScaffoldDestinationItem(
- pane = it[0] as ThreePaneScaffoldRole,
- content = it[1] as T?
- )
- }
- )
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ThreePaneScaffoldDestinationItem<*>) return false
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldHorizontalOrder.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt
similarity index 96%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldHorizontalOrder.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt
index 131e717..589c663 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldHorizontalOrder.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldHorizontalOrder.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.runtime.Immutable
import androidx.compose.ui.unit.LayoutDirection
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldState.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldState.kt
similarity index 92%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldState.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldState.kt
index 4e02b85..8d4bc0f 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldState.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldState.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.runtime.Stable
/**
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValue.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt
similarity index 98%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValue.kt
rename to compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt
index 4f28529..fd9b397 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValue.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValue.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.layout
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
import androidx.compose.runtime.Immutable
import androidx.compose.ui.util.fastForEachReversed
diff --git a/compose/material3/adaptive/adaptive-navigation/api/current.txt b/compose/material3/adaptive/adaptive-navigation/api/current.txt
new file mode 100644
index 0000000..f3c507c
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-navigation/api/current.txt
@@ -0,0 +1,32 @@
+// Signature format: 4.0
+package androidx.compose.material3.adaptive.navigation {
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum BackNavigationBehavior {
+ method public static androidx.compose.material3.adaptive.navigation.BackNavigationBehavior valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static androidx.compose.material3.adaptive.navigation.BackNavigationBehavior[] values();
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopLatest;
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopUntilContentChange;
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopUntilCurrentDestinationChange;
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopUntilScaffoldValueChange;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldNavigator<T> {
+ method public boolean canNavigateBack(optional androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior);
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<T>? getCurrentDestination();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState getScaffoldState();
+ method public boolean isDestinationHistoryAware();
+ method public boolean navigateBack(optional androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior);
+ method public void navigateTo(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole pane, optional T? content);
+ method public void setDestinationHistoryAware(boolean);
+ property public abstract androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<T>? currentDestination;
+ property public abstract boolean isDestinationHistoryAware;
+ property public abstract androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState scaffoldState;
+ }
+
+ public final class ThreePaneScaffoldNavigatorKt {
+ 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 <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/material3-adaptive/api/res-current.txt b/compose/material3/adaptive/adaptive-navigation/api/res-current.txt
similarity index 100%
copy from compose/material3/material3-adaptive/api/res-current.txt
copy to compose/material3/adaptive/adaptive-navigation/api/res-current.txt
diff --git a/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt b/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt
new file mode 100644
index 0000000..f3c507c
--- /dev/null
+++ b/compose/material3/adaptive/adaptive-navigation/api/restricted_current.txt
@@ -0,0 +1,32 @@
+// Signature format: 4.0
+package androidx.compose.material3.adaptive.navigation {
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum BackNavigationBehavior {
+ method public static androidx.compose.material3.adaptive.navigation.BackNavigationBehavior valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static androidx.compose.material3.adaptive.navigation.BackNavigationBehavior[] values();
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopLatest;
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopUntilContentChange;
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopUntilCurrentDestinationChange;
+ enum_constant public static final androidx.compose.material3.adaptive.navigation.BackNavigationBehavior PopUntilScaffoldValueChange;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldNavigator<T> {
+ method public boolean canNavigateBack(optional androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior);
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<T>? getCurrentDestination();
+ method public androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState getScaffoldState();
+ method public boolean isDestinationHistoryAware();
+ method public boolean navigateBack(optional androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior);
+ method public void navigateTo(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole pane, optional T? content);
+ method public void setDestinationHistoryAware(boolean);
+ property public abstract androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem<T>? currentDestination;
+ property public abstract boolean isDestinationHistoryAware;
+ property public abstract androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState scaffoldState;
+ }
+
+ public final class ThreePaneScaffoldNavigatorKt {
+ 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 <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/material3-adaptive/build.gradle b/compose/material3/adaptive/adaptive-navigation/build.gradle
similarity index 90%
copy from compose/material3/material3-adaptive/build.gradle
copy to compose/material3/adaptive/adaptive-navigation/build.gradle
index cbd842e..3736767 100644
--- a/compose/material3/material3-adaptive/build.gradle
+++ b/compose/material3/adaptive/adaptive-navigation/build.gradle
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 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.
@@ -23,7 +23,6 @@
*/
import androidx.build.LibraryType
import androidx.build.PlatformIdentifier
-import androidx.build.Publish
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@@ -45,6 +44,7 @@
api("androidx.compose.foundation:foundation:1.6.0-rc01")
implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
+ implementation(project(":compose:material3:adaptive:adaptive-layout"))
// TODO(conradchen): pin the depe when the change required is released to public
implementation(project(":window:window-core"))
}
@@ -67,7 +67,6 @@
dependencies {
api("androidx.annotation:annotation:1.1.0")
api("androidx.annotation:annotation-experimental:1.4.0")
- implementation("androidx.window:window:1.2.0")
}
}
@@ -110,12 +109,11 @@
}
android {
- namespace "androidx.compose.material3.adaptive"
+ namespace "androidx.compose.material3.adaptive.navigation"
}
androidx {
name = "Material Adaptive"
- mavenVersion = LibraryVersions.COMPOSE_MATERIAL3_ADAPTIVE
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2023"
description = "Compose Material Design Adaptive Library"
@@ -128,6 +126,6 @@
// Screenshot tests related setup
android {
sourceSets.androidTest.assets.srcDirs +=
- project.rootDir.absolutePath + "/../../golden/compose/material3/material3-adaptive"
- namespace "androidx.compose.material3.adaptive"
+ project.rootDir.absolutePath + "/../../golden/compose/material3/adaptive"
+ namespace "androidx.compose.material3.adaptive.navigation"
}
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffoldNavigatorTest.kt b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt
similarity index 97%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffoldNavigatorTest.kt
rename to compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt
index efdd348..603fd04d 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/ListDetailPaneScaffoldNavigatorTest.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/ListDetailPaneScaffoldNavigatorTest.kt
@@ -14,9 +14,15 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.navigation
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
+import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.dp
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffoldNavigatorTest.kt b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt
similarity index 97%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffoldNavigatorTest.kt
rename to compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt
index bd224dc..8ef7193 100644
--- a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/SupportingPaneScaffoldNavigatorTest.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation/SupportingPaneScaffoldNavigatorTest.kt
@@ -14,9 +14,15 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.navigation
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
+import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.dp
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/BackNavigationBehavior.kt b/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/BackNavigationBehavior.kt
similarity index 84%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/BackNavigationBehavior.kt
rename to compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/BackNavigationBehavior.kt
index 6332068..3ae80e2 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/BackNavigationBehavior.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/BackNavigationBehavior.kt
@@ -14,7 +14,12 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.navigation
+
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.layout.PaneAdaptedValue
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole
/**
* A class to control how back navigation should behave in a [ThreePaneScaffoldNavigator].
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldNavigator.kt b/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt
similarity index 89%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldNavigator.kt
rename to compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt
index a8a181f..e4c9e79 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldNavigator.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation/ThreePaneScaffoldNavigator.kt
@@ -14,8 +14,24 @@
* limitations under the License.
*/
-package androidx.compose.material3.adaptive
+package androidx.compose.material3.adaptive.navigation
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldDefaults
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffold
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldDefaults
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldAdaptStrategies
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldState
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue
+import androidx.compose.material3.adaptive.layout.calculateStandardPaneScaffoldDirective
+import androidx.compose.material3.adaptive.layout.calculateThreePaneScaffoldValue
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
@@ -29,7 +45,8 @@
import androidx.compose.ui.util.fastMap
/**
- * The common interface of the default navigation implementations for different [ThreePaneScaffold].
+ * The common interface of the default navigation implementations for different three-pane
+ * scaffolds.
*
* In general, we suggest you to use [rememberListDetailPaneScaffoldNavigator] or
* [rememberSupportingPaneScaffoldNavigator] to get remembered default instances of this interface
@@ -329,7 +346,7 @@
initialAdaptStrategies: ThreePaneScaffoldAdaptStrategies,
initialDestinationHistoryAware: Boolean
): Saver<DefaultThreePaneScaffoldNavigator<T>, *> {
- val destinationItemSaver = ThreePaneScaffoldDestinationItem.saver<T>()
+ val destinationItemSaver = destinationItemSaver<T>()
return listSaver(
save = {
it.destinationHistory.fastMap { destination ->
@@ -350,6 +367,18 @@
}
}
}
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+internal fun <T> destinationItemSaver(): Saver<ThreePaneScaffoldDestinationItem<T>, Any> =
+ listSaver(
+ save = { listOf(it.pane, it.content) },
+ restore = {
+ @Suppress("UNCHECKED_CAST")
+ (ThreePaneScaffoldDestinationItem(
+ pane = it[0] as ThreePaneScaffoldRole,
+ content = it[1] as T?
+ ))
+ }
+ )
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
private val DefaultListDetailPaneHistory: List<ThreePaneScaffoldDestinationItem<Nothing>> =
diff --git a/compose/material3/adaptive/adaptive/api/current.txt b/compose/material3/adaptive/adaptive/api/current.txt
new file mode 100644
index 0000000..b7dcb35
--- /dev/null
+++ b/compose/material3/adaptive/adaptive/api/current.txt
@@ -0,0 +1,55 @@
+// Signature format: 4.0
+package androidx.compose.material3.adaptive {
+
+ public final class AndroidPosture_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.Posture calculatePosture(java.util.List<? extends androidx.window.layout.FoldingFeature> foldingFeatures);
+ }
+
+ public final class AndroidWindowAdaptiveInfo_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.util.List<androidx.window.layout.FoldingFeature>> collectFoldingFeaturesAsState();
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.WindowAdaptiveInfo currentWindowAdaptiveInfo();
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static long currentWindowSize();
+ }
+
+ @SuppressCompatibility @kotlin.RequiresOptIn(message="This material3 adaptive API is experimental and is likely to change or to be" + "removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3AdaptiveApi {
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class HingeInfo {
+ ctor public HingeInfo(androidx.compose.ui.geometry.Rect bounds, boolean isVertical, boolean isSeparating, boolean isOccluding);
+ method public androidx.compose.ui.geometry.Rect getBounds();
+ method public boolean isOccluding();
+ method public boolean isSeparating();
+ method public boolean isVertical();
+ property public final androidx.compose.ui.geometry.Rect bounds;
+ property public final boolean isOccluding;
+ property public final boolean isSeparating;
+ property public final boolean isVertical;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class Posture {
+ ctor public Posture(optional boolean isTabletop, optional java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList);
+ method public java.util.List<androidx.compose.material3.adaptive.HingeInfo> getHingeList();
+ method public boolean isTabletop();
+ property public final java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList;
+ property public final boolean isTabletop;
+ }
+
+ public final class PostureKt {
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class WindowAdaptiveInfo {
+ ctor public WindowAdaptiveInfo(androidx.window.core.layout.WindowSizeClass windowSizeClass, androidx.compose.material3.adaptive.Posture windowPosture);
+ method public androidx.compose.material3.adaptive.Posture getWindowPosture();
+ method public androidx.window.core.layout.WindowSizeClass getWindowSizeClass();
+ property public final androidx.compose.material3.adaptive.Posture windowPosture;
+ property public final androidx.window.core.layout.WindowSizeClass windowSizeClass;
+ }
+
+}
+
diff --git a/compose/material3/material3-adaptive/api/res-current.txt b/compose/material3/adaptive/adaptive/api/res-current.txt
similarity index 100%
rename from compose/material3/material3-adaptive/api/res-current.txt
rename to compose/material3/adaptive/adaptive/api/res-current.txt
diff --git a/compose/material3/adaptive/adaptive/api/restricted_current.txt b/compose/material3/adaptive/adaptive/api/restricted_current.txt
new file mode 100644
index 0000000..b7dcb35
--- /dev/null
+++ b/compose/material3/adaptive/adaptive/api/restricted_current.txt
@@ -0,0 +1,55 @@
+// Signature format: 4.0
+package androidx.compose.material3.adaptive {
+
+ public final class AndroidPosture_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.Posture calculatePosture(java.util.List<? extends androidx.window.layout.FoldingFeature> foldingFeatures);
+ }
+
+ public final class AndroidWindowAdaptiveInfo_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.util.List<androidx.window.layout.FoldingFeature>> collectFoldingFeaturesAsState();
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.WindowAdaptiveInfo currentWindowAdaptiveInfo();
+ method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static long currentWindowSize();
+ }
+
+ @SuppressCompatibility @kotlin.RequiresOptIn(message="This material3 adaptive API is experimental and is likely to change or to be" + "removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3AdaptiveApi {
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class HingeInfo {
+ ctor public HingeInfo(androidx.compose.ui.geometry.Rect bounds, boolean isVertical, boolean isSeparating, boolean isOccluding);
+ method public androidx.compose.ui.geometry.Rect getBounds();
+ method public boolean isOccluding();
+ method public boolean isSeparating();
+ method public boolean isVertical();
+ property public final androidx.compose.ui.geometry.Rect bounds;
+ property public final boolean isOccluding;
+ property public final boolean isSeparating;
+ property public final boolean isVertical;
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class Posture {
+ ctor public Posture(optional boolean isTabletop, optional java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList);
+ method public java.util.List<androidx.compose.material3.adaptive.HingeInfo> getHingeList();
+ method public boolean isTabletop();
+ property public final java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList;
+ property public final boolean isTabletop;
+ }
+
+ public final class PostureKt {
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
+ }
+
+ @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class WindowAdaptiveInfo {
+ ctor public WindowAdaptiveInfo(androidx.window.core.layout.WindowSizeClass windowSizeClass, androidx.compose.material3.adaptive.Posture windowPosture);
+ method public androidx.compose.material3.adaptive.Posture getWindowPosture();
+ method public androidx.window.core.layout.WindowSizeClass getWindowSizeClass();
+ property public final androidx.compose.material3.adaptive.Posture windowPosture;
+ property public final androidx.window.core.layout.WindowSizeClass windowSizeClass;
+ }
+
+}
+
diff --git a/compose/material3/material3-adaptive/build.gradle b/compose/material3/adaptive/adaptive/build.gradle
similarity index 93%
rename from compose/material3/material3-adaptive/build.gradle
rename to compose/material3/adaptive/adaptive/build.gradle
index cbd842e..17f440f 100644
--- a/compose/material3/material3-adaptive/build.gradle
+++ b/compose/material3/adaptive/adaptive/build.gradle
@@ -23,7 +23,6 @@
*/
import androidx.build.LibraryType
import androidx.build.PlatformIdentifier
-import androidx.build.Publish
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@@ -42,9 +41,8 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
- api("androidx.compose.foundation:foundation:1.6.0-rc01")
- implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
- implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
+ api("androidx.compose.foundation:foundation:1.6.0")
+ implementation("androidx.compose.ui:ui-util:1.6.0")
// TODO(conradchen): pin the depe when the change required is released to public
implementation(project(":window:window-core"))
}
@@ -115,7 +113,6 @@
androidx {
name = "Material Adaptive"
- mavenVersion = LibraryVersions.COMPOSE_MATERIAL3_ADAPTIVE
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2023"
description = "Compose Material Design Adaptive Library"
@@ -128,6 +125,6 @@
// Screenshot tests related setup
android {
sourceSets.androidTest.assets.srcDirs +=
- project.rootDir.absolutePath + "/../../golden/compose/material3/material3-adaptive"
+ project.rootDir.absolutePath + "/../../golden/compose/material3/adaptive"
namespace "androidx.compose.material3.adaptive"
}
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CalculatePostureTest.kt b/compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CalculatePostureTest.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CalculatePostureTest.kt
rename to compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CalculatePostureTest.kt
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectFoldingFeaturesAsStateTest.kt b/compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectFoldingFeaturesAsStateTest.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectFoldingFeaturesAsStateTest.kt
rename to compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectFoldingFeaturesAsStateTest.kt
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectWindowSizeAsStateTest.kt b/compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectWindowSizeAsStateTest.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectWindowSizeAsStateTest.kt
rename to compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CollectWindowSizeAsStateTest.kt
diff --git a/compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CurrentWindowAdaptiveInfoTest.kt b/compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CurrentWindowAdaptiveInfoTest.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CurrentWindowAdaptiveInfoTest.kt
rename to compose/material3/adaptive/adaptive/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/CurrentWindowAdaptiveInfoTest.kt
diff --git a/compose/material3/material3-adaptive/src/androidMain/AndroidManifest.xml b/compose/material3/adaptive/adaptive/src/androidMain/AndroidManifest.xml
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidMain/AndroidManifest.xml
rename to compose/material3/adaptive/adaptive/src/androidMain/AndroidManifest.xml
diff --git a/compose/material3/material3-adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidPosture.android.kt b/compose/material3/adaptive/adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidPosture.android.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidPosture.android.kt
rename to compose/material3/adaptive/adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidPosture.android.kt
diff --git a/compose/material3/material3-adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidWindowInfo.android.kt b/compose/material3/adaptive/adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidWindowAdaptiveInfo.android.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidWindowInfo.android.kt
rename to compose/material3/adaptive/adaptive/src/androidMain/kotlin/androidx/compose/material3/adaptive/AndroidWindowAdaptiveInfo.android.kt
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ExperimentalMaterial3AdaptiveApi.kt b/compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ExperimentalMaterial3AdaptiveApi.kt
similarity index 92%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ExperimentalMaterial3AdaptiveApi.kt
rename to compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ExperimentalMaterial3AdaptiveApi.kt
index 4636316..3ad72c5 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ExperimentalMaterial3AdaptiveApi.kt
+++ b/compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ExperimentalMaterial3AdaptiveApi.kt
@@ -17,7 +17,7 @@
package androidx.compose.material3.adaptive
@RequiresOptIn(
- "This material3-adaptive API is experimental and is likely to change or to be" +
+ "This material3 adaptive API is experimental and is likely to change or to be" +
"removed in the future."
)
@Retention(AnnotationRetention.BINARY)
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt b/compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt
rename to compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt b/compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
similarity index 80%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
rename to compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
index de1f979..57b2015 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
+++ b/compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
@@ -16,10 +16,22 @@
package androidx.compose.material3.adaptive
+import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.window.core.layout.WindowSizeClass
/**
+ * Calculates and returns [WindowAdaptiveInfo] of the provided context. It's a convenient function
+ * that uses the default [WindowSizeClass] constructor and the default [Posture] calculation
+ * functions to retrieve [WindowSizeClass] and [Posture].
+ *
+ * @return [WindowAdaptiveInfo] of the provided context
+ */
+@ExperimentalMaterial3AdaptiveApi
+@Composable
+expect fun currentWindowAdaptiveInfo(): WindowAdaptiveInfo
+
+/**
* This class collects window info that affects adaptation decisions. An adaptive layout is supposed
* to use the info from this class to decide how the layout is supposed to be adapted.
*
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/androidx-compose-material3-adaptive-documentation.md b/compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/androidx-compose-material3-adaptive-documentation.md
similarity index 100%
rename from compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/androidx-compose-material3-adaptive-documentation.md
rename to compose/material3/adaptive/adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/androidx-compose-material3-adaptive-documentation.md
diff --git a/compose/material3/material3-adaptive/src/desktopMain/kotlin/androidx/compose/material3/adaptive/DesktopWindowInfo.desktop.kt b/compose/material3/adaptive/adaptive/src/desktopMain/kotlin/androidx/compose/material3/adaptive/DesktopWindowInfo.desktop.kt
similarity index 100%
rename from compose/material3/material3-adaptive/src/desktopMain/kotlin/androidx/compose/material3/adaptive/DesktopWindowInfo.desktop.kt
rename to compose/material3/adaptive/adaptive/src/desktopMain/kotlin/androidx/compose/material3/adaptive/DesktopWindowInfo.desktop.kt
diff --git a/compose/material3/material3-adaptive/benchmark/build.gradle b/compose/material3/adaptive/benchmark/build.gradle
similarity index 93%
rename from compose/material3/material3-adaptive/benchmark/build.gradle
rename to compose/material3/adaptive/benchmark/build.gradle
index 48f6444..e63b29e 100644
--- a/compose/material3/material3-adaptive/benchmark/build.gradle
+++ b/compose/material3/adaptive/benchmark/build.gradle
@@ -23,7 +23,7 @@
}
dependencies {
- androidTestImplementation(project(":compose:material3:material3-adaptive"))
+ androidTestImplementation(project(":compose:material3:adaptive:adaptive-layout"))
androidTestImplementation(project(":benchmark:benchmark-junit4"))
androidTestImplementation(project(":compose:runtime:runtime"))
androidTestImplementation(project(":compose:benchmark-utils"))
diff --git a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt b/compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt
similarity index 95%
rename from compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt
rename to compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt
index b6974a1..2a48785 100644
--- a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt
+++ b/compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt
@@ -17,10 +17,10 @@
package androidx.compose.material3.adaptive.benchmark
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
-import androidx.compose.material3.adaptive.ListDetailPaneScaffold
-import androidx.compose.material3.adaptive.ListDetailPaneScaffoldRole
-import androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem
-import androidx.compose.material3.adaptive.calculateListDetailPaneScaffoldState
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.calculateListDetailPaneScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt b/compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt
similarity index 95%
rename from compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt
rename to compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt
index a96d4d9..dcfaec7 100644
--- a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt
+++ b/compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt
@@ -17,10 +17,10 @@
package androidx.compose.material3.adaptive.benchmark
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
-import androidx.compose.material3.adaptive.SupportingPaneScaffold
-import androidx.compose.material3.adaptive.SupportingPaneScaffoldRole
-import androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem
-import androidx.compose.material3.adaptive.calculateSupportingPaneScaffoldState
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffold
+import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.calculateSupportingPaneScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt b/compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt
similarity index 90%
rename from compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt
rename to compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt
index c71021b..acfcf48 100644
--- a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt
+++ b/compose/material3/adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt
@@ -20,11 +20,11 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.material3.adaptive.AnimatedPane
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
-import androidx.compose.material3.adaptive.PaneScaffoldDirective
-import androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem
-import androidx.compose.material3.adaptive.ThreePaneScaffoldScope
+import androidx.compose.material3.adaptive.layout.AnimatedPane
+import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldDestinationItem
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/material3/material3-adaptive/samples/build.gradle b/compose/material3/adaptive/samples/build.gradle
similarity index 92%
rename from compose/material3/material3-adaptive/samples/build.gradle
rename to compose/material3/adaptive/samples/build.gradle
index 1c8ac3c..45dec1d 100644
--- a/compose/material3/material3-adaptive/samples/build.gradle
+++ b/compose/material3/adaptive/samples/build.gradle
@@ -38,8 +38,9 @@
implementation("androidx.compose.foundation:foundation:1.6.0-rc01")
implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
+ implementation(project(":compose:material3:adaptive:adaptive-layout"))
+ implementation(project(":compose:material3:adaptive:adaptive-navigation"))
implementation(project(":compose:material3:material3"))
- implementation(project(":compose:material3:material3-adaptive"))
implementation(project(":compose:material3:material3-window-size-class"))
implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
implementation("androidx.compose.ui:ui-tooling-preview:1.4.1")
diff --git a/compose/material3/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
similarity index 94%
rename from compose/material3/material3-adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
rename to compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
index 5ddc87f..29d75b0 100644
--- a/compose/material3/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
@@ -29,11 +29,11 @@
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
-import androidx.compose.material3.adaptive.AnimatedPane
import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
-import androidx.compose.material3.adaptive.ListDetailPaneScaffold
-import androidx.compose.material3.adaptive.ListDetailPaneScaffoldRole
-import androidx.compose.material3.adaptive.rememberListDetailPaneScaffoldNavigator
+import androidx.compose.material3.adaptive.layout.AnimatedPane
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
+import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
+import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
diff --git a/compose/material3/material3-adaptive-navigation-suite/build.gradle b/compose/material3/material3-adaptive-navigation-suite/build.gradle
index 47289bf..769a941 100644
--- a/compose/material3/material3-adaptive-navigation-suite/build.gradle
+++ b/compose/material3/material3-adaptive-navigation-suite/build.gradle
@@ -43,9 +43,9 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
- implementation("androidx.compose.material3:material3:1.2.0-rc01")
- implementation(project(":compose:material3:material3-adaptive"))
- implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
+ implementation("androidx.compose.material3:material3:1.2.0")
+ implementation(project(":compose:material3:adaptive:adaptive"))
+ implementation("androidx.compose.ui:ui-util:1.6.0")
// TODO(conradchen): pin the depe when the change required is released to public
implementation(project(":window:window-core"))
}
@@ -110,6 +110,9 @@
android {
namespace "androidx.compose.material3.adaptive.navigationsuite"
+ lintOptions {
+ disable 'IllegalExperimentalApiUsage' // TODO (conradchen): Address before moving to beta
+ }
}
androidx {
diff --git a/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle b/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle
index 2e1bb69..135d478 100644
--- a/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle
+++ b/compose/material3/material3-adaptive-navigation-suite/samples/build.gradle
@@ -38,8 +38,8 @@
implementation("androidx.compose.foundation:foundation:1.6.0-rc01")
implementation("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
+ implementation(project(":compose:material3:adaptive:adaptive"))
implementation(project(":compose:material3:material3"))
- implementation(project(":compose:material3:material3-adaptive"))
implementation(project(":compose:material3:material3-adaptive-navigation-suite"))
implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
implementation("androidx.compose.ui:ui-tooling-preview:1.4.1")
diff --git a/compose/material3/material3-adaptive/api/current.txt b/compose/material3/material3-adaptive/api/current.txt
deleted file mode 100644
index ade4688..0000000
--- a/compose/material3/material3-adaptive/api/current.txt
+++ /dev/null
@@ -1,254 +0,0 @@
-// Signature format: 4.0
-package androidx.compose.material3.adaptive {
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface AdaptStrategy {
- method public String adapt();
- field public static final androidx.compose.material3.adaptive.AdaptStrategy.Companion Companion;
- }
-
- public static final class AdaptStrategy.Companion {
- method public androidx.compose.material3.adaptive.AdaptStrategy getHide();
- property public final androidx.compose.material3.adaptive.AdaptStrategy Hide;
- }
-
- public final class AndroidPosture_androidKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.Posture calculatePosture(java.util.List<? extends androidx.window.layout.FoldingFeature> foldingFeatures);
- }
-
- public final class AndroidWindowInfo_androidKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.util.List<androidx.window.layout.FoldingFeature>> collectFoldingFeaturesAsState();
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.WindowAdaptiveInfo currentWindowAdaptiveInfo();
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static long currentWindowSize();
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum BackNavigationBehavior {
- method public static androidx.compose.material3.adaptive.BackNavigationBehavior valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
- method public static androidx.compose.material3.adaptive.BackNavigationBehavior[] values();
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopLatest;
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopUntilContentChange;
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopUntilCurrentDestinationChange;
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopUntilScaffoldValueChange;
- }
-
- @SuppressCompatibility @kotlin.RequiresOptIn(message="This material3-adaptive API is experimental and is likely to change or to be" + "removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3AdaptiveApi {
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class HingeInfo {
- ctor public HingeInfo(androidx.compose.ui.geometry.Rect bounds, boolean isVertical, boolean isSeparating, boolean isOccluding);
- method public androidx.compose.ui.geometry.Rect getBounds();
- method public boolean isOccluding();
- method public boolean isSeparating();
- method public boolean isVertical();
- property public final androidx.compose.ui.geometry.Rect bounds;
- property public final boolean isOccluding;
- property public final boolean isSeparating;
- property public final boolean isVertical;
- }
-
- @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class HingePolicy {
- field public static final androidx.compose.material3.adaptive.HingePolicy.Companion Companion;
- }
-
- public static final class HingePolicy.Companion {
- method public int getAlwaysAvoid();
- method public int getAvoidOccluding();
- method public int getAvoidSeparating();
- method public int getNeverAvoid();
- property public final int AlwaysAvoid;
- property public final int AvoidOccluding;
- property public final int AvoidSeparating;
- property public final int NeverAvoid;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldDefaults {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.AdaptStrategy detailPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy listPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy extraPaneAdaptStrategy);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
- property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
- field public static final androidx.compose.material3.adaptive.ListDetailPaneScaffoldDefaults INSTANCE;
- }
-
- public final class ListDetailPaneScaffoldKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void ListDetailPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> listPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> detailPane);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(optional androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldRole {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getDetail();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getExtra();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getList();
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Detail;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Extra;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole List;
- field public static final androidx.compose.material3.adaptive.ListDetailPaneScaffoldRole INSTANCE;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedValue {
- field public static final androidx.compose.material3.adaptive.PaneAdaptedValue.Companion Companion;
- }
-
- public static final class PaneAdaptedValue.Companion {
- method public String getExpanded();
- method public String getHidden();
- property public final String Expanded;
- property public final String Hidden;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class PaneScaffoldDirective {
- ctor public PaneScaffoldDirective(androidx.compose.foundation.layout.PaddingValues contentPadding, int maxHorizontalPartitions, float horizontalPartitionSpacerSize, int maxVerticalPartitions, float verticalPartitionSpacerSize, java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds);
- method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
- method public java.util.List<androidx.compose.ui.geometry.Rect> getExcludedBounds();
- method public float getHorizontalPartitionSpacerSize();
- method public int getMaxHorizontalPartitions();
- method public int getMaxVerticalPartitions();
- method public float getVerticalPartitionSpacerSize();
- property public final androidx.compose.foundation.layout.PaddingValues contentPadding;
- property public final java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds;
- property public final float horizontalPartitionSpacerSize;
- property public final int maxHorizontalPartitions;
- property public final int maxVerticalPartitions;
- property public final float verticalPartitionSpacerSize;
- }
-
- public final class PaneScaffoldDirectiveKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.PaneScaffoldDirective calculateDensePaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.PaneScaffoldDirective calculateStandardPaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface PaneScaffoldScope {
- method public androidx.compose.ui.Modifier preferredWidth(androidx.compose.ui.Modifier, float width);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class Posture {
- ctor public Posture(optional boolean isTabletop, optional java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList);
- method public java.util.List<androidx.compose.material3.adaptive.HingeInfo> getHingeList();
- method public boolean isTabletop();
- property public final java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList;
- property public final boolean isTabletop;
- }
-
- public final class PostureKt {
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldDefaults {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.AdaptStrategy mainPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy supportingPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy extraPaneAdaptStrategy);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
- property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
- field public static final androidx.compose.material3.adaptive.SupportingPaneScaffoldDefaults INSTANCE;
- }
-
- public final class SupportingPaneScaffoldKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void SupportingPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> supportingPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> mainPane);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(optional androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldRole {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getExtra();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getMain();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getSupporting();
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Extra;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Main;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Supporting;
- field public static final androidx.compose.material3.adaptive.SupportingPaneScaffoldRole INSTANCE;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldAdaptStrategies {
- ctor public ThreePaneScaffoldAdaptStrategies(androidx.compose.material3.adaptive.AdaptStrategy primaryPaneAdaptStrategy, androidx.compose.material3.adaptive.AdaptStrategy secondaryPaneAdaptStrategy, androidx.compose.material3.adaptive.AdaptStrategy tertiaryPaneAdaptStrategy);
- method public operator androidx.compose.material3.adaptive.AdaptStrategy get(androidx.compose.material3.adaptive.ThreePaneScaffoldRole role);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldDestinationItem<T> {
- ctor public ThreePaneScaffoldDestinationItem(androidx.compose.material3.adaptive.ThreePaneScaffoldRole pane, optional T? content);
- method public T? getContent();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getPane();
- property public final T? content;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole pane;
- field public static final androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem.Companion Companion;
- }
-
- public static final class ThreePaneScaffoldDestinationItem.Companion {
- }
-
- public final class ThreePaneScaffoldKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void AnimatedPane(androidx.compose.material3.adaptive.ThreePaneScaffoldScope, androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> content);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldNavigator<T> {
- method public boolean canNavigateBack(optional androidx.compose.material3.adaptive.BackNavigationBehavior backNavigationBehavior);
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<T>? getCurrentDestination();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldState getScaffoldState();
- method public boolean isDestinationHistoryAware();
- method public boolean navigateBack(optional androidx.compose.material3.adaptive.BackNavigationBehavior backNavigationBehavior);
- method public void navigateTo(androidx.compose.material3.adaptive.ThreePaneScaffoldRole pane, optional T? content);
- method public void setDestinationHistoryAware(boolean);
- property public abstract androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<T>? currentDestination;
- property public abstract boolean isDestinationHistoryAware;
- property public abstract androidx.compose.material3.adaptive.ThreePaneScaffoldState scaffoldState;
- }
-
- public final class ThreePaneScaffoldNavigatorKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.ThreePaneScaffoldNavigator<T> rememberListDetailPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.ThreePaneScaffoldNavigator<T> rememberSupportingPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum ThreePaneScaffoldRole {
- method public static androidx.compose.material3.adaptive.ThreePaneScaffoldRole valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
- method public static androidx.compose.material3.adaptive.ThreePaneScaffoldRole[] values();
- enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Primary;
- enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Secondary;
- enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Tertiary;
- }
-
- public interface ThreePaneScaffoldScope extends androidx.compose.material3.adaptive.PaneScaffoldScope {
- method public String getAnimationToolingLabel();
- method public androidx.compose.animation.EnterTransition getEnterTransition();
- method public androidx.compose.animation.ExitTransition getExitTransition();
- method public String getPaneAdaptedValue();
- method public androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? getPositionAnimationSpec();
- property public abstract String animationToolingLabel;
- property public abstract androidx.compose.animation.EnterTransition enterTransition;
- property public abstract androidx.compose.animation.ExitTransition exitTransition;
- property public abstract String paneAdaptedValue;
- property public abstract androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? positionAnimationSpec;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldState {
- method public androidx.compose.material3.adaptive.PaneScaffoldDirective getScaffoldDirective();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldValue getScaffoldValue();
- property public abstract androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective;
- property public abstract androidx.compose.material3.adaptive.ThreePaneScaffoldValue scaffoldValue;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class ThreePaneScaffoldValue {
- ctor public ThreePaneScaffoldValue(String primary, String secondary, String tertiary);
- method public operator String get(androidx.compose.material3.adaptive.ThreePaneScaffoldRole role);
- method public String getPrimary();
- method public String getSecondary();
- method public String getTertiary();
- property public final String primary;
- property public final String secondary;
- property public final String tertiary;
- }
-
- public final class ThreePaneScaffoldValueKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>? currentDestination);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>> destinationHistory);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class WindowAdaptiveInfo {
- ctor public WindowAdaptiveInfo(androidx.window.core.layout.WindowSizeClass windowSizeClass, androidx.compose.material3.adaptive.Posture windowPosture);
- method public androidx.compose.material3.adaptive.Posture getWindowPosture();
- method public androidx.window.core.layout.WindowSizeClass getWindowSizeClass();
- property public final androidx.compose.material3.adaptive.Posture windowPosture;
- property public final androidx.window.core.layout.WindowSizeClass windowSizeClass;
- }
-
-}
-
diff --git a/compose/material3/material3-adaptive/api/restricted_current.txt b/compose/material3/material3-adaptive/api/restricted_current.txt
deleted file mode 100644
index ade4688..0000000
--- a/compose/material3/material3-adaptive/api/restricted_current.txt
+++ /dev/null
@@ -1,254 +0,0 @@
-// Signature format: 4.0
-package androidx.compose.material3.adaptive {
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface AdaptStrategy {
- method public String adapt();
- field public static final androidx.compose.material3.adaptive.AdaptStrategy.Companion Companion;
- }
-
- public static final class AdaptStrategy.Companion {
- method public androidx.compose.material3.adaptive.AdaptStrategy getHide();
- property public final androidx.compose.material3.adaptive.AdaptStrategy Hide;
- }
-
- public final class AndroidPosture_androidKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.Posture calculatePosture(java.util.List<? extends androidx.window.layout.FoldingFeature> foldingFeatures);
- }
-
- public final class AndroidWindowInfo_androidKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.util.List<androidx.window.layout.FoldingFeature>> collectFoldingFeaturesAsState();
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.WindowAdaptiveInfo currentWindowAdaptiveInfo();
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static long currentWindowSize();
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum BackNavigationBehavior {
- method public static androidx.compose.material3.adaptive.BackNavigationBehavior valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
- method public static androidx.compose.material3.adaptive.BackNavigationBehavior[] values();
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopLatest;
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopUntilContentChange;
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopUntilCurrentDestinationChange;
- enum_constant public static final androidx.compose.material3.adaptive.BackNavigationBehavior PopUntilScaffoldValueChange;
- }
-
- @SuppressCompatibility @kotlin.RequiresOptIn(message="This material3-adaptive API is experimental and is likely to change or to be" + "removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3AdaptiveApi {
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class HingeInfo {
- ctor public HingeInfo(androidx.compose.ui.geometry.Rect bounds, boolean isVertical, boolean isSeparating, boolean isOccluding);
- method public androidx.compose.ui.geometry.Rect getBounds();
- method public boolean isOccluding();
- method public boolean isSeparating();
- method public boolean isVertical();
- property public final androidx.compose.ui.geometry.Rect bounds;
- property public final boolean isOccluding;
- property public final boolean isSeparating;
- property public final boolean isVertical;
- }
-
- @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class HingePolicy {
- field public static final androidx.compose.material3.adaptive.HingePolicy.Companion Companion;
- }
-
- public static final class HingePolicy.Companion {
- method public int getAlwaysAvoid();
- method public int getAvoidOccluding();
- method public int getAvoidSeparating();
- method public int getNeverAvoid();
- property public final int AlwaysAvoid;
- property public final int AvoidOccluding;
- property public final int AvoidSeparating;
- property public final int NeverAvoid;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldDefaults {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.AdaptStrategy detailPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy listPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy extraPaneAdaptStrategy);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
- property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
- field public static final androidx.compose.material3.adaptive.ListDetailPaneScaffoldDefaults INSTANCE;
- }
-
- public final class ListDetailPaneScaffoldKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void ListDetailPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> listPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> detailPane);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(optional androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateListDetailPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailPaneScaffoldRole {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getDetail();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getExtra();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getList();
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Detail;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Extra;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole List;
- field public static final androidx.compose.material3.adaptive.ListDetailPaneScaffoldRole INSTANCE;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedValue {
- field public static final androidx.compose.material3.adaptive.PaneAdaptedValue.Companion Companion;
- }
-
- public static final class PaneAdaptedValue.Companion {
- method public String getExpanded();
- method public String getHidden();
- property public final String Expanded;
- property public final String Hidden;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class PaneScaffoldDirective {
- ctor public PaneScaffoldDirective(androidx.compose.foundation.layout.PaddingValues contentPadding, int maxHorizontalPartitions, float horizontalPartitionSpacerSize, int maxVerticalPartitions, float verticalPartitionSpacerSize, java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds);
- method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
- method public java.util.List<androidx.compose.ui.geometry.Rect> getExcludedBounds();
- method public float getHorizontalPartitionSpacerSize();
- method public int getMaxHorizontalPartitions();
- method public int getMaxVerticalPartitions();
- method public float getVerticalPartitionSpacerSize();
- property public final androidx.compose.foundation.layout.PaddingValues contentPadding;
- property public final java.util.List<androidx.compose.ui.geometry.Rect> excludedBounds;
- property public final float horizontalPartitionSpacerSize;
- property public final int maxHorizontalPartitions;
- property public final int maxVerticalPartitions;
- property public final float verticalPartitionSpacerSize;
- }
-
- public final class PaneScaffoldDirectiveKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.PaneScaffoldDirective calculateDensePaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.PaneScaffoldDirective calculateStandardPaneScaffoldDirective(androidx.compose.material3.adaptive.WindowAdaptiveInfo windowAdaptiveInfo, optional int verticalHingePolicy);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public interface PaneScaffoldScope {
- method public androidx.compose.ui.Modifier preferredWidth(androidx.compose.ui.Modifier, float width);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class Posture {
- ctor public Posture(optional boolean isTabletop, optional java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList);
- method public java.util.List<androidx.compose.material3.adaptive.HingeInfo> getHingeList();
- method public boolean isTabletop();
- property public final java.util.List<androidx.compose.material3.adaptive.HingeInfo> hingeList;
- property public final boolean isTabletop;
- }
-
- public final class PostureKt {
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getAllVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getOccludingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingHorizontalHingeBounds(androidx.compose.material3.adaptive.Posture);
- method public static java.util.List<androidx.compose.ui.geometry.Rect> getSeparatingVerticalHingeBounds(androidx.compose.material3.adaptive.Posture);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldDefaults {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies(optional androidx.compose.material3.adaptive.AdaptStrategy mainPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy supportingPaneAdaptStrategy, optional androidx.compose.material3.adaptive.AdaptStrategy extraPaneAdaptStrategy);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.layout.WindowInsets getWindowInsets();
- property @androidx.compose.runtime.Composable public final androidx.compose.foundation.layout.WindowInsets windowInsets;
- field public static final androidx.compose.material3.adaptive.SupportingPaneScaffoldDefaults INSTANCE;
- }
-
- public final class SupportingPaneScaffoldKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void SupportingPaneScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> supportingPane, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.adaptive.ThreePaneScaffoldState scaffoldState, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit>? extraPane, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> mainPane);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(optional androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?> currentDestination, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static androidx.compose.material3.adaptive.ThreePaneScaffoldState calculateSupportingPaneScaffoldState(java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>> destinationHistory, optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneScaffoldRole {
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getExtra();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getMain();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getSupporting();
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Extra;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Main;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Supporting;
- field public static final androidx.compose.material3.adaptive.SupportingPaneScaffoldRole INSTANCE;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldAdaptStrategies {
- ctor public ThreePaneScaffoldAdaptStrategies(androidx.compose.material3.adaptive.AdaptStrategy primaryPaneAdaptStrategy, androidx.compose.material3.adaptive.AdaptStrategy secondaryPaneAdaptStrategy, androidx.compose.material3.adaptive.AdaptStrategy tertiaryPaneAdaptStrategy);
- method public operator androidx.compose.material3.adaptive.AdaptStrategy get(androidx.compose.material3.adaptive.ThreePaneScaffoldRole role);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldDestinationItem<T> {
- ctor public ThreePaneScaffoldDestinationItem(androidx.compose.material3.adaptive.ThreePaneScaffoldRole pane, optional T? content);
- method public T? getContent();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldRole getPane();
- property public final T? content;
- property public final androidx.compose.material3.adaptive.ThreePaneScaffoldRole pane;
- field public static final androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem.Companion Companion;
- }
-
- public static final class ThreePaneScaffoldDestinationItem.Companion {
- }
-
- public final class ThreePaneScaffoldKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static void AnimatedPane(androidx.compose.material3.adaptive.ThreePaneScaffoldScope, androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.adaptive.ThreePaneScaffoldScope,kotlin.Unit> content);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldNavigator<T> {
- method public boolean canNavigateBack(optional androidx.compose.material3.adaptive.BackNavigationBehavior backNavigationBehavior);
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<T>? getCurrentDestination();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldState getScaffoldState();
- method public boolean isDestinationHistoryAware();
- method public boolean navigateBack(optional androidx.compose.material3.adaptive.BackNavigationBehavior backNavigationBehavior);
- method public void navigateTo(androidx.compose.material3.adaptive.ThreePaneScaffoldRole pane, optional T? content);
- method public void setDestinationHistoryAware(boolean);
- property public abstract androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<T>? currentDestination;
- property public abstract boolean isDestinationHistoryAware;
- property public abstract androidx.compose.material3.adaptive.ThreePaneScaffoldState scaffoldState;
- }
-
- public final class ThreePaneScaffoldNavigatorKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.ThreePaneScaffoldNavigator<T> rememberListDetailPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material3.adaptive.ThreePaneScaffoldNavigator<T> rememberSupportingPaneScaffoldNavigator(optional androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective, optional androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, optional boolean isDestinationHistoryAware, optional java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<? extends T>> initialDestinationHistory);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public enum ThreePaneScaffoldRole {
- method public static androidx.compose.material3.adaptive.ThreePaneScaffoldRole valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
- method public static androidx.compose.material3.adaptive.ThreePaneScaffoldRole[] values();
- enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Primary;
- enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Secondary;
- enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Tertiary;
- }
-
- public interface ThreePaneScaffoldScope extends androidx.compose.material3.adaptive.PaneScaffoldScope {
- method public String getAnimationToolingLabel();
- method public androidx.compose.animation.EnterTransition getEnterTransition();
- method public androidx.compose.animation.ExitTransition getExitTransition();
- method public String getPaneAdaptedValue();
- method public androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? getPositionAnimationSpec();
- property public abstract String animationToolingLabel;
- property public abstract androidx.compose.animation.EnterTransition enterTransition;
- property public abstract androidx.compose.animation.ExitTransition exitTransition;
- property public abstract String paneAdaptedValue;
- property public abstract androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>? positionAnimationSpec;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Stable public interface ThreePaneScaffoldState {
- method public androidx.compose.material3.adaptive.PaneScaffoldDirective getScaffoldDirective();
- method public androidx.compose.material3.adaptive.ThreePaneScaffoldValue getScaffoldValue();
- property public abstract androidx.compose.material3.adaptive.PaneScaffoldDirective scaffoldDirective;
- property public abstract androidx.compose.material3.adaptive.ThreePaneScaffoldValue scaffoldValue;
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class ThreePaneScaffoldValue {
- ctor public ThreePaneScaffoldValue(String primary, String secondary, String tertiary);
- method public operator String get(androidx.compose.material3.adaptive.ThreePaneScaffoldRole role);
- method public String getPrimary();
- method public String getSecondary();
- method public String getTertiary();
- property public final String primary;
- property public final String secondary;
- property public final String tertiary;
- }
-
- public final class ThreePaneScaffoldValueKt {
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>? currentDestination);
- method @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public static androidx.compose.material3.adaptive.ThreePaneScaffoldValue calculateThreePaneScaffoldValue(int maxHorizontalPartitions, androidx.compose.material3.adaptive.ThreePaneScaffoldAdaptStrategies adaptStrategies, java.util.List<? extends androidx.compose.material3.adaptive.ThreePaneScaffoldDestinationItem<?>> destinationHistory);
- }
-
- @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class WindowAdaptiveInfo {
- ctor public WindowAdaptiveInfo(androidx.window.core.layout.WindowSizeClass windowSizeClass, androidx.compose.material3.adaptive.Posture windowPosture);
- method public androidx.compose.material3.adaptive.Posture getWindowPosture();
- method public androidx.window.core.layout.WindowSizeClass getWindowSizeClass();
- property public final androidx.compose.material3.adaptive.Posture windowPosture;
- property public final androidx.window.core.layout.WindowSizeClass windowSizeClass;
- }
-
-}
-
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowInfo.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowInfo.kt
deleted file mode 100644
index dca80dd..0000000
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowInfo.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.compose.material3.adaptive
-
-import androidx.compose.runtime.Composable
-import androidx.window.core.layout.WindowSizeClass
-
-/**
- * Calculates and returns [WindowAdaptiveInfo] of the provided context. It's a convenient function
- * that uses the default [WindowSizeClass] constructor and the default [Posture] calculation
- * functions to retrieve [WindowSizeClass] and [Posture].
- *
- * @return [WindowAdaptiveInfo] of the provided context
- */
-@ExperimentalMaterial3AdaptiveApi
-@Composable
-expect fun currentWindowAdaptiveInfo(): WindowAdaptiveInfo
diff --git a/compose/material3/material3-common/build.gradle b/compose/material3/material3-common/build.gradle
index 09fa42b..804a2d2 100644
--- a/compose/material3/material3-common/build.gradle
+++ b/compose/material3/material3-common/build.gradle
@@ -42,14 +42,12 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
-
- api(project(":compose:foundation:foundation"))
- api(project(":compose:foundation:foundation-layout"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui-graphics"))
- api(project(":compose:ui:ui-text"))
-
implementation(project(":compose:ui:ui-util"))
+ api("androidx.compose.foundation:foundation:1.6.0")
+ api("androidx.compose.foundation:foundation-layout:1.6.0")
+ api("androidx.compose.runtime:runtime:1.6.0")
+ api("androidx.compose.ui:ui-graphics:1.6.0")
+ api("androidx.compose.ui:ui-text:1.6.0")
}
}
androidMain.dependencies {
@@ -77,7 +75,6 @@
desktopMain {
dependsOn(jvmMain)
dependencies {
- implementation(libs.kotlinStdlib)
}
}
diff --git a/compose/material3/material3-window-size-class/build.gradle b/compose/material3/material3-window-size-class/build.gradle
index ed1e25f..8ae1969 100644
--- a/compose/material3/material3-window-size-class/build.gradle
+++ b/compose/material3/material3-window-size-class/build.gradle
@@ -40,10 +40,10 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
- implementation(project(":compose:ui:ui-util"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-unit"))
+ implementation("androidx.compose.ui:ui-util:1.6.0")
+ api("androidx.compose.runtime:runtime:1.6.0")
+ api("androidx.compose.ui:ui:1.6.0")
+ api("androidx.compose.ui:ui-unit:1.6.0")
}
}
@@ -63,11 +63,6 @@
skikoMain {
dependsOn(commonMain)
dependencies {
- // Because dependencies are pinned in the android/common code.
- implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
- api("androidx.compose.runtime:runtime:1.6.0-rc01")
- api("androidx.compose.ui:ui:1.6.0-rc01")
- api("androidx.compose.ui:ui-unit:1.6.0-rc01")
}
}
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index 101f313..aa50925 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -28,7 +28,6 @@
id("AndroidXPlugin")
id("com.android.library")
id("AndroidXComposePlugin")
- id("AndroidXPaparazziPlugin")
}
androidXMultiplatform {
@@ -43,16 +42,15 @@
implementation(libs.kotlinStdlibCommon)
// Keep pinned unless there is a need for tip of tree behavior
implementation("androidx.collection:collection:1.4.0")
- implementation(project(":compose:animation:animation-core"))
-
+ implementation("androidx.compose.animation:animation-core:1.6.0")
+ implementation("androidx.compose.ui:ui-util:1.6.0")
api(project(":compose:foundation:foundation"))
- api(project(":compose:foundation:foundation-layout"))
- api(project(":compose:material:material-icons-core"))
+ api("androidx.compose.foundation:foundation-layout:1.6.0")
+ api("androidx.compose.material:material-icons-core:1.6.0")
api(project(":compose:material:material-ripple"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-text"))
- implementation(project(":compose:ui:ui-util"))
+ api("androidx.compose.runtime:runtime:1.6.0")
+ api("androidx.compose.ui:ui:1.6.0")
+ api("androidx.compose.ui:ui-text:1.6.0")
}
}
@@ -70,14 +68,6 @@
skikoMain {
dependsOn(commonMain)
dependencies {
- api(project(":compose:animation:animation-core"))
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-text"))
- api(project(":compose:foundation:foundation-layout"))
-
- implementation(project(":compose:animation:animation"))
- implementation(project(":compose:ui:ui-util"))
}
}
diff --git a/compose/material3/material3/integration-tests/material3-catalog/build.gradle b/compose/material3/material3/integration-tests/material3-catalog/build.gradle
index c7aeee6..699cb55 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/build.gradle
+++ b/compose/material3/material3/integration-tests/material3-catalog/build.gradle
@@ -39,9 +39,9 @@
implementation project(":compose:ui:ui")
implementation project(":compose:material:material")
implementation project(":compose:material:material-icons-extended")
+ implementation project(":compose:material3:adaptive:adaptive-samples")
implementation project(":compose:material3:material3")
implementation project(":compose:material3:material3:material3-samples")
- implementation project(":compose:material3:material3-adaptive:material3-adaptive-samples")
implementation project(":compose:material3:material3-adaptive-navigation-suite:material3-adaptive-navigation-suite-samples")
implementation project(":datastore:datastore-preferences")
implementation project(":navigation:navigation-compose")
diff --git a/compose/material3/material3/lint-baseline.xml b/compose/material3/material3/lint-baseline.xml
index dc2af50..f59d635 100644
--- a/compose/material3/material3/lint-baseline.xml
+++ b/compose/material3/material3/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanThreadSleep"
@@ -40,24 +40,6 @@
<issue
id="BanThreadSleep"
message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(300)"
- errorLine2=" ~~~~~">
- <location
- file="src/androidInstrumentedTest/kotlin/androidx/compose/material3/MaterialRippleThemeTest.kt"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(300)"
- errorLine2=" ~~~~~">
- <location
- file="src/androidInstrumentedTest/kotlin/androidx/compose/material3/MaterialRippleThemeTest.kt"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
errorLine1=" Thread.sleep(300)"
errorLine2=" ~~~~~">
<location
@@ -284,24 +266,6 @@
<issue
id="PrimitiveInCollection"
- message="variable xCandidates with type List<? extends Integer>: replace with IntList"
- errorLine1=" val xCandidates = listOf("
- errorLine2=" ^">
- <location
- file="src/commonMain/kotlin/androidx/compose/material3/MenuPosition.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable yCandidates with type List<? extends Integer>: replace with IntList"
- errorLine1=" val yCandidates = listOf("
- errorLine2=" ^">
- <location
- file="src/commonMain/kotlin/androidx/compose/material3/MenuPosition.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
message="variable tabContentWidths with type List<Dp>: replace with FloatList"
errorLine1=" val tabContentWidths = mutableListOf<Dp>()"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/ButtonPaparazziTest.kt b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/ButtonPaparazziTest.kt
deleted file mode 100644
index e386d4e..0000000
--- a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/ButtonPaparazziTest.kt
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.material3
-
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.wrapContentSize
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Favorite
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.unit.dp
-import androidx.testutils.paparazzi.androidxPaparazzi
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class ButtonPaparazziTest {
- @get:Rule
- val paparazzi = androidxPaparazzi()
-
- @Test
- fun default_button_light_theme() {
- paparazzi.snapshot {
- MaterialTheme(lightColorScheme()) {
- Surface {
- Button(onClick = { }) {
- Text("Button")
- }
- }
- }
- }
- }
-
- @Test
- fun default_button_dark_theme() {
- paparazzi.snapshot {
- MaterialTheme(darkColorScheme()) {
- Surface {
- Button(onClick = { }) {
- Text("Button")
- }
- }
- }
- }
- }
-
- @Test
- fun disabled_button_light_theme() {
- paparazzi.snapshot {
- MaterialTheme(lightColorScheme()) {
- Surface {
- Button(onClick = { }, enabled = false) {
- Text("Button")
- }
- }
- }
- }
- }
-
- @Test
- fun disabled_button_dark_theme() {
- paparazzi.snapshot {
- MaterialTheme(darkColorScheme()) {
- Surface {
- Button(onClick = { }, enabled = false) {
- Text("Button")
- }
- }
- }
- }
- }
-
- @Test
- fun elevated_button_light_theme() {
- paparazzi.snapshot {
- MaterialTheme(lightColorScheme()) {
- Surface {
- Box(
- Modifier.requiredSize(
- 200.dp,
- 100.dp
- ).wrapContentSize().testTag("elevated button")
- ) {
- ElevatedButton(onClick = {}) { Text("Elevated Button") }
- }
- }
- }
- }
- }
-
- @Test
- fun elevated_button_dark_theme() {
- paparazzi.snapshot {
- MaterialTheme(darkColorScheme()) {
- Surface {
- Box(
- Modifier.requiredSize(
- 200.dp,
- 100.dp
- ).wrapContentSize().testTag("elevated button")
- ) {
- ElevatedButton(onClick = {}) { Text("Elevated Button") }
- }
- }
- }
- }
- }
-
- @Test
- fun disabled_elevated_button_light_theme() {
- paparazzi.snapshot {
- MaterialTheme(lightColorScheme()) {
- Surface {
- Box(
- Modifier.requiredSize(
- 200.dp,
- 100.dp
- ).wrapContentSize().testTag("elevated button")
- ) {
- ElevatedButton(onClick = {}, enabled = false) { Text("Elevated Button") }
- }
- }
- }
- }
- }
-
- @Test
- fun disabled_elevated_button_dark_theme() {
- paparazzi.snapshot {
- MaterialTheme(darkColorScheme()) {
- Surface {
- Box(
- Modifier.requiredSize(
- 200.dp,
- 100.dp
- ).wrapContentSize().testTag("elevated button")
- ) {
- ElevatedButton(onClick = {}, enabled = false) { Text("Elevated Button") }
- }
- }
- }
- }
- }
-
- @Test
- fun button_with_icon_light_theme() {
- paparazzi.snapshot {
- MaterialTheme(lightColorScheme()) {
- Surface {
- Button(
- onClick = { /* Do something! */ },
- contentPadding = ButtonDefaults.ButtonWithIconContentPadding
- ) {
- Icon(
- Icons.Filled.Favorite,
- contentDescription = "Localized description",
- modifier = Modifier.size(ButtonDefaults.IconSize)
- )
- Spacer(Modifier.size(ButtonDefaults.IconSpacing))
- Text("Like")
- }
- }
- }
- }
- }
-
- @Test
- fun button_with_icon_dark_theme() {
- paparazzi.snapshot {
- MaterialTheme(darkColorScheme()) {
- Surface {
- Button(
- onClick = { /* Do something! */ },
- contentPadding = ButtonDefaults.ButtonWithIconContentPadding
- ) {
- Icon(
- Icons.Filled.Favorite,
- contentDescription = "Localized description",
- modifier = Modifier.size(ButtonDefaults.IconSize)
- )
- Spacer(Modifier.size(ButtonDefaults.IconSpacing))
- Text("Like")
- }
- }
- }
- }
- }
-
- @Test
- fun disabled_button_with_icon_light_theme() {
- paparazzi.snapshot {
- MaterialTheme(lightColorScheme()) {
- Surface {
- Button(
- onClick = { /* Do something! */ },
- contentPadding = ButtonDefaults.ButtonWithIconContentPadding,
- enabled = false,
- ) {
- Icon(
- Icons.Filled.Favorite,
- contentDescription = "Localized description",
- modifier = Modifier.size(ButtonDefaults.IconSize)
- )
- Spacer(Modifier.size(ButtonDefaults.IconSpacing))
- Text("Like")
- }
- }
- }
- }
- }
-
- @Test
- fun disabled_button_with_icon_dark_theme() {
- paparazzi.snapshot {
- MaterialTheme(darkColorScheme()) {
- Surface {
- Button(
- onClick = { /* Do something! */ },
- contentPadding = ButtonDefaults.ButtonWithIconContentPadding,
- enabled = false,
- ) {
- Icon(
- Icons.Filled.Favorite,
- contentDescription = "Localized description",
- modifier = Modifier.size(ButtonDefaults.IconSize)
- )
- Spacer(Modifier.size(ButtonDefaults.IconSpacing))
- Text("Like")
- }
- }
- }
- }
- }
-}
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt
index 2b6d054..1583cc5 100644
--- a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt
+++ b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt
@@ -25,13 +25,13 @@
@RunWith(JUnit4::class)
class MultiBrowseTest {
- private val density = Density(1f)
+ private val Density = Density(1f)
@Test
fun testMultiBrowse_doesNotResizeLargeWhenEnoughRoom() {
val itemSize = 120f // minSmallItemSize = 40.dp * 3
val keylineList = multiBrowseKeylineList(
- density = density,
+ density = Density,
carouselMainAxisSize = 500f,
preferredItemSize = itemSize,
itemSpacing = 0f
@@ -48,7 +48,7 @@
fun testMultiBrowse_resizesItemLargerThanContainerToFit1Small() {
val itemSize = 200f
val keylineList = multiBrowseKeylineList(
- density = density,
+ density = Density,
carouselMainAxisSize = 100f,
preferredItemSize = itemSize,
itemSpacing = 0f
@@ -58,7 +58,7 @@
carouselMainAxisSize = 100f,
keylineList = keylineList
)
- val minSmallItemSize: Float = with(density) { StrategyDefaults.minSmallSize.toPx() }
+ val minSmallItemSize: Float = with(Density) { StrategyDefaults.MinSmallSize.toPx() }
val keylines = strategy.getDefaultKeylines()
// If the item size given is larger than the container, the adjusted keyline list from
@@ -73,9 +73,9 @@
@Test
fun testMultiBrowse_hasNoSmallItemsIfNotEnoughRoom() {
- val minSmallItemSize: Float = with(density) { StrategyDefaults.minSmallSize.toPx() }
+ val minSmallItemSize: Float = with(Density) { StrategyDefaults.MinSmallSize.toPx() }
val keylineList = multiBrowseKeylineList(
- density = density,
+ density = Density,
carouselMainAxisSize = minSmallItemSize,
preferredItemSize = 200f,
itemSpacing = 0f
@@ -94,7 +94,7 @@
@Test
fun testMultiBrowse_isNullIfAvailableSpaceIsZero() {
val keylineList = multiBrowseKeylineList(
- density = density,
+ density = Density,
carouselMainAxisSize = 0f,
preferredItemSize = 200f,
itemSpacing = 0f
@@ -104,11 +104,11 @@
@Test
fun testMultiBrowse_adjustsMediumSizeToBeProportional() {
- val maxSmallItemSize: Float = with(density) { StrategyDefaults.maxSmallSize.toPx() }
+ val maxSmallItemSize: Float = with(Density) { StrategyDefaults.MaxSmallSize.toPx() }
val preferredItemSize = 200f
val carouselSize = preferredItemSize * 2 + maxSmallItemSize * 2
val keylineList = multiBrowseKeylineList(
- density = density,
+ density = Density,
carouselMainAxisSize = carouselSize,
preferredItemSize = preferredItemSize,
itemSpacing = 0f
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt
new file mode 100644
index 0000000..0110805
--- /dev/null
+++ b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt
@@ -0,0 +1,150 @@
+/*
+ * 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.compose.material3.carousel
+
+import androidx.compose.ui.unit.Density
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class UncontainedTest {
+
+ private val Density = Density(1f)
+
+ @Test
+ fun testLargeItem_withFullCarouselWidth() {
+ val itemSize = 500f
+ val carouselSize = 500f
+ val keylineList = uncontainedKeylineList(
+ density = Density,
+ carouselMainAxisSize = carouselSize,
+ itemSize = itemSize,
+ itemSpacing = 0f
+ )!!
+ val strategy = Strategy.create(
+ carouselMainAxisSize = carouselSize,
+ keylineList = keylineList
+ )
+ val keylines = strategy.getDefaultKeylines()
+ val anchorSize = with(Density) { StrategyDefaults.AnchorSize.toPx() }
+
+ // A fullscreen layout should be [xSmall-large-xSmall] where the xSmall items are
+ // outside the bounds of the carousel container and the large item takes up the
+ // containers full width.
+ assertThat(keylines.size).isEqualTo(3)
+ assertThat(keylines[0].offset).isEqualTo(-anchorSize / 2f)
+ assertThat(keylines[1].size).isEqualTo(carouselSize)
+ assertThat(keylines[2].offset).isEqualTo(carouselSize + anchorSize / 2f)
+ }
+
+ @Test
+ fun testLargeItem_largerThanFullCarouselWidth() {
+ val carouselSize = 400f
+ val itemSize = 500f
+ val keylineList = uncontainedKeylineList(
+ density = Density,
+ carouselMainAxisSize = carouselSize,
+ itemSize = itemSize,
+ itemSpacing = 0f
+ )!!
+ val strategy = Strategy.create(
+ carouselMainAxisSize = carouselSize,
+ keylineList = keylineList
+ )
+ val keylines = strategy.getDefaultKeylines()
+ val anchorSize = with(Density) { StrategyDefaults.AnchorSize.toPx() }
+
+ // The layout should be [xSmall-large-xSmall] where the xSmall items are
+ // outside the bounds of the carousel container and the large item takes up the
+ // containers full width.
+ assertThat(keylines.size).isEqualTo(3)
+ assertThat(keylines[0].offset).isEqualTo(-anchorSize / 2f)
+ assertThat(keylines[1].size).isEqualTo(carouselSize)
+ assertThat(keylines[2].offset).isEqualTo(carouselSize + anchorSize / 2f)
+ }
+
+ @Test
+ fun testRemainingSpaceWithItemSize_fitsItemWithThirdCutoff() {
+ val carouselSize = 400f
+ // With size 125px, 3 large items can fit with in 400px, with 25px left. 25px * 3 = 75px,
+ // which will be the size of the medium item since it can be a third cut off and it is less
+ // than the threshold percentage * large item size.
+ val itemSize = 125f
+ val keylineList = uncontainedKeylineList(
+ density = Density,
+ carouselMainAxisSize = carouselSize,
+ itemSize = itemSize,
+ itemSpacing = 0f
+ )!!
+ val strategy = Strategy.create(
+ carouselMainAxisSize = carouselSize,
+ keylineList = keylineList
+ )
+ val keylines = strategy.getDefaultKeylines()
+
+ // The layout should be [xSmall-large-large-large-medium-xSmall] where medium is a size
+ // such that a third of it is cut off.
+ assertThat(keylines.size).isEqualTo(6)
+ assertThat(keylines[1].size).isEqualTo(itemSize)
+ assertThat(keylines[2].size).isEqualTo(itemSize)
+ assertThat(keylines[3].size).isEqualTo(itemSize)
+ // The cutoff size should be a size that has a third of itself cut off with the given
+ // remaining space, which is 25f as explained above.
+ assertThat(keylines[4].size).isEqualTo(25f * 1.5f)
+ assertThat(keylines[4].offset).isEqualTo(393.75f) // itemSize * 3 + (25 * 1.5f / 2)
+ assertThat(keylines[0].size).isEqualTo(18.75f) // half the med size is the anchor size
+ assertThat(keylines[0].offset).isEqualTo(-9.375f) // -18.75f/2
+ assertThat(keylines[5].offset)
+ .isEqualTo(421.875f) // itemSize*3 + 25f * 1.5f + 18.75f/2
+ }
+
+ @Test
+ fun testRemainingSpaceWithItemSize_fitsMediumItemWithCutoff() {
+ val carouselSize = 400f
+ // With size 105px, 3 large items can fit with in 400px, with 85px left over. 85*3 = 255
+ // which is well over the size of the large item, so the medium size will be limited to
+ // whichever is larger between 85% of the large size, or 110% of the remainingSpace to make
+ // it at most 10% cut off.
+ val itemSize = 105f
+ val keylineList = uncontainedKeylineList(
+ density = Density,
+ carouselMainAxisSize = carouselSize,
+ itemSize = itemSize,
+ itemSpacing = 0f
+ )!!
+ val strategy = Strategy.create(
+ carouselMainAxisSize = carouselSize,
+ keylineList = keylineList
+ )
+ val keylines = strategy.getDefaultKeylines()
+
+ // The layout should be [xSmall-large-large-large-medium-xSmall]
+ assertThat(keylines.size).isEqualTo(6)
+ assertThat(keylines[1].size).isEqualTo(itemSize)
+ assertThat(keylines[2].size).isEqualTo(itemSize)
+ assertThat(keylines[3].size).isEqualTo(itemSize)
+ // remainingSpace * 120%
+ assertThat(keylines[4].size).isEqualTo(85 * 1.2f)
+ assertThat(keylines[0].size).isEqualTo(85 * 1.2f * 0.5f)
+ assertThat(keylines[5].size).isEqualTo(85 * 1.2f * 0.5f)
+ assertThat(keylines[0].offset).isEqualTo(-(85 * 1.2f * 0.5f) / 2f)
+ assertThat(keylines[5].offset)
+ .isEqualTo(itemSize * 3 + 85 * 1.2f + (85 * 1.2f * 0.5f) / 2f)
+ }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
index 8982afe..9dd4eb7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
@@ -56,20 +56,18 @@
* For more information, see <a href="https://material.io/components/carousel/overview">design
* guidelines</a>.
*
- * @param state The state object to be used to control the carousel's state.
+ * @param state The state object to be used to control the carousel's state
* @param preferredItemSize The size fully visible items would like to be in the main axis. This
* size is a target and will likely be adjusted by carousel in order to fit a whole number of
- * items within the container.
- * @param modifier A modifier instance to be applied to this carousel outer layout
+ * items within the container
+ * @param modifier A modifier instance to be applied to this carousel container
* @param itemSpacing The amount of space used to separate items in the carousel
* @param minSmallSize The minimum allowable size of small masked items
* @param maxSmallSize The maximum allowable size of small masked items
- * @param content The carousel's content Composable.
+ * @param content The carousel's content Composable
*
* TODO: Add sample link
*/
-@Suppress("IllegalExperimentalApiUsage")
-@OptIn(ExperimentalFoundationApi::class)
@ExperimentalMaterial3Api
@Composable
internal fun HorizontalMultiBrowseCarousel(
@@ -77,9 +75,9 @@
preferredItemSize: Dp,
modifier: Modifier = Modifier,
itemSpacing: Dp = 0.dp,
- minSmallSize: Dp = StrategyDefaults.minSmallSize,
- maxSmallSize: Dp = StrategyDefaults.maxSmallSize,
- content: @Composable CarouselScope.(item: Int) -> Unit
+ minSmallSize: Dp = StrategyDefaults.MinSmallSize,
+ maxSmallSize: Dp = StrategyDefaults.MaxSmallSize,
+ content: @Composable CarouselScope.(itemIndex: Int) -> Unit
) {
val density = LocalDensity.current
Carousel(
@@ -106,6 +104,56 @@
/**
* <a href=https://m3.material.io/components/carousel/overview" class="external" target="_blank">Material Design Carousel</a>
*
+ * A horizontal carousel that displays its items with the given size except for one item at the end
+ * that is cut off.
+ *
+ * Note that the item size will be bound by the size of the carousel. Otherwise, this carousel lays
+ * out as many items as it can in the given size, and changes the size of the last cut off item such
+ * that there is a range of motion when items scroll off the edge.
+ *
+ * For more information, see <a href="https://material.io/components/carousel/overview">design
+ * guidelines</a>.
+ *
+ * @param state The state object to be used to control the carousel's state
+ * @param itemSize The size of items in the carousel
+ * @param modifier A modifier instance to be applied to this carousel container
+ * @param itemSpacing The amount of space used to separate items in the carousel
+ * @param content The carousel's content Composable
+ *
+ * TODO: Add sample link
+ */
+@ExperimentalMaterial3Api
+@Composable
+internal fun HorizontalUncontainedCarousel(
+ state: CarouselState,
+ itemSize: Dp,
+ modifier: Modifier = Modifier,
+ itemSpacing: Dp = 0.dp,
+ content: @Composable CarouselScope.(itemIndex: Int) -> Unit
+) {
+ val density = LocalDensity.current
+ Carousel(
+ state = state,
+ orientation = Orientation.Horizontal,
+ keylineList = {
+ with(density) {
+ uncontainedKeylineList(
+ density = this,
+ carouselMainAxisSize = state.pagerState.layoutInfo.viewportSize.width.toFloat(),
+ itemSize = itemSize.toPx(),
+ itemSpacing = itemSpacing.toPx(),
+ )
+ }
+ },
+ modifier = modifier,
+ itemSpacing = itemSpacing,
+ content = content
+ )
+}
+
+/**
+ * <a href=https://m3.material.io/components/carousel/overview" class="external" target="_blank">Material Design Carousel</a>
+ *
* Carousels contain a collection of items that changes sizes according to their placement and the
* chosen strategy.
*
@@ -119,10 +167,6 @@
* total item count, of the item being composed
* TODO: Add sample link
*/
-// TODO: b/321997456 - Remove lint suppression once version checks are added in lint or library
-// moves to beta
-@Suppress("IllegalExperimentalApiUsage")
-@OptIn(ExperimentalFoundationApi::class)
@ExperimentalMaterial3Api
@Composable
internal fun Carousel(
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Keyline.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/KeylineList.kt
similarity index 82%
rename from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Keyline.kt
rename to compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/KeylineList.kt
index c445137..653d829 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Keyline.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/KeylineList.kt
@@ -16,101 +16,9 @@
package androidx.compose.material3.carousel
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.util.fastFirstOrNull
import androidx.compose.ui.util.fastMapIndexed
import kotlin.math.abs
-import kotlin.math.ceil
-import kotlin.math.floor
-import kotlin.math.max
-import kotlin.math.min
-
-/**
- * Creates a list of keylines that arranges items into a multi-browse configuration.
- *
- * Note that this function may adjust the size of large items. In order to ensure large, medium,
- * and small items fit perfectly into the available space and are numbered/arranged in a
- * visually pleasing and opinionated way, this strategy finds the nearest number of large items that
- * will fit into an approved arrangement that requires the least amount of size adjustment
- * necessary.
- *
- * For more information, see <a href="https://material.io/components/carousel/overview">design
- * guidelines</a>.
- *
- * @param density The [Density] object that provides pixel density information of the device
- * @param carouselMainAxisSize the size of the carousel container, in pixels, in the main
- * scrolling axis
- * @param preferredItemSize the desired size of large items, in pixels, in the main scrolling axis
- * @param itemSpacing the spacing between items in pixels
- * @param minSmallSize the minimum allowable size of small items in pixels
- * @param maxSmallSize the maximum allowable size of small items in pixels
- */
-internal fun multiBrowseKeylineList(
- density: Density,
- carouselMainAxisSize: Float,
- preferredItemSize: Float,
- itemSpacing: Float,
- minSmallSize: Float = with(density) { StrategyDefaults.minSmallSize.toPx() },
- maxSmallSize: Float = with(density) { StrategyDefaults.maxSmallSize.toPx() },
-): KeylineList? {
- if (carouselMainAxisSize == 0f || preferredItemSize == 0f) {
- return null
- }
-
- var smallCounts: IntArray = intArrayOf(1)
- val mediumCounts: IntArray = intArrayOf(1, 0)
-
- val targetLargeSize: Float = min(preferredItemSize + itemSpacing, carouselMainAxisSize)
- // Ideally we would like to create a balanced arrangement where a small item is 1/3 the size
- // of the large item and medium items are sized between large and small items. Clamp the
- // small target size within our min-max range and as close to 1/3 of the target large item
- // size as possible.
- val targetSmallSize: Float = (targetLargeSize / 3f + itemSpacing).coerceIn(
- minSmallSize + itemSpacing,
- maxSmallSize + itemSpacing
- )
- val targetMediumSize = (targetLargeSize + targetSmallSize) / 2f
-
- if (carouselMainAxisSize < minSmallSize * 2) {
- // If the available space is too small to fit a large item and small item (where a large
- // item is bigger than a small item), allow arrangements with
- // no small items.
- smallCounts = intArrayOf(0)
- }
-
- // Find the minimum space left for large items after filling the carousel with the most
- // permissible medium and small items to determine a plausible minimum large count.
- val minAvailableLargeSpace = carouselMainAxisSize - targetMediumSize * mediumCounts.max() -
- maxSmallSize * smallCounts.max()
- val minLargeCount = max(
- 1,
- floor(minAvailableLargeSpace / targetLargeSize).toInt())
- val maxLargeCount = ceil(carouselMainAxisSize / targetLargeSize).toInt()
-
- val largeCounts = IntArray(maxLargeCount - minLargeCount + 1) { maxLargeCount - it }
- val anchorSize = with(density) { StrategyDefaults.anchorSize.toPx() }
- val arrangement = Arrangement.findLowestCostArrangement(
- availableSpace = carouselMainAxisSize,
- targetSmallSize = targetSmallSize,
- minSmallSize = minSmallSize,
- maxSmallSize = maxSmallSize,
- smallCounts = smallCounts,
- targetMediumSize = targetMediumSize,
- mediumCounts = mediumCounts,
- targetLargeSize = targetLargeSize,
- largeCounts = largeCounts,
- ) ?: return null
-
- return keylineListOf(carouselMainAxisSize, CarouselAlignment.Start) {
- add(anchorSize, isAnchor = true)
-
- repeat(arrangement.largeCount) { add(arrangement.largeSize) }
- repeat(arrangement.mediumCount) { add(arrangement.mediumSize) }
- repeat(arrangement.smallCount) { add(arrangement.smallSize) }
-
- add(anchorSize, isAnchor = true)
- }
-}
/**
* A structure that is fixed at a specific [offset] along a scrolling axis and
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Keylines.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Keylines.kt
new file mode 100644
index 0000000..7d281be
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Keylines.kt
@@ -0,0 +1,212 @@
+/*
+ * 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.compose.material3.carousel
+
+import androidx.compose.ui.unit.Density
+import kotlin.math.ceil
+import kotlin.math.floor
+import kotlin.math.max
+import kotlin.math.min
+
+/**
+ * Creates a list of keylines that arranges items into a multi-browse configuration.
+ *
+ * Note that this function may adjust the size of large items. In order to ensure large, medium,
+ * and small items fit perfectly into the available space and are numbered/arranged in a
+ * visually pleasing and opinionated way, this strategy finds the nearest number of large items that
+ * will fit into an approved arrangement that requires the least amount of size adjustment
+ * necessary.
+ *
+ * For more information, see <a href="https://material.io/components/carousel/overview">design
+ * guidelines</a>.
+ *
+ * @param density The [Density] object that provides pixel density information of the device
+ * @param carouselMainAxisSize The carousel container's pixel size in the main scrolling axis
+ * @param preferredItemSize the desired size of large items, in pixels, in the main scrolling axis
+ * @param itemSpacing the spacing between items in pixels
+ * @param minSmallSize the minimum allowable size of small items in pixels
+ * @param maxSmallSize the maximum allowable size of small items in pixels
+ */
+internal fun multiBrowseKeylineList(
+ density: Density,
+ carouselMainAxisSize: Float,
+ preferredItemSize: Float,
+ itemSpacing: Float,
+ minSmallSize: Float = with(density) { StrategyDefaults.MinSmallSize.toPx() },
+ maxSmallSize: Float = with(density) { StrategyDefaults.MaxSmallSize.toPx() },
+): KeylineList? {
+ if (carouselMainAxisSize == 0f || preferredItemSize == 0f) {
+ return null
+ }
+
+ var smallCounts: IntArray = intArrayOf(1)
+ val mediumCounts: IntArray = intArrayOf(1, 0)
+
+ val targetLargeSize: Float = min(preferredItemSize + itemSpacing, carouselMainAxisSize)
+ // Ideally we would like to create a balanced arrangement where a small item is 1/3 the size
+ // of the large item and medium items are sized between large and small items. Clamp the
+ // small target size within our min-max range and as close to 1/3 of the target large item
+ // size as possible.
+ val targetSmallSize: Float = (targetLargeSize / 3f + itemSpacing).coerceIn(
+ minSmallSize + itemSpacing,
+ maxSmallSize + itemSpacing
+ )
+ val targetMediumSize = (targetLargeSize + targetSmallSize) / 2f
+
+ if (carouselMainAxisSize < minSmallSize * 2) {
+ // If the available space is too small to fit a large item and small item (where a large
+ // item is bigger than a small item), allow arrangements with
+ // no small items.
+ smallCounts = intArrayOf(0)
+ }
+
+ // Find the minimum space left for large items after filling the carousel with the most
+ // permissible medium and small items to determine a plausible minimum large count.
+ val minAvailableLargeSpace = carouselMainAxisSize - targetMediumSize * mediumCounts.max() -
+ maxSmallSize * smallCounts.max()
+ val minLargeCount = max(
+ 1,
+ floor(minAvailableLargeSpace / targetLargeSize).toInt())
+ val maxLargeCount = ceil(carouselMainAxisSize / targetLargeSize).toInt()
+
+ val largeCounts = IntArray(maxLargeCount - minLargeCount + 1) { maxLargeCount - it }
+ val anchorSize = with(density) { StrategyDefaults.AnchorSize.toPx() }
+ val arrangement = Arrangement.findLowestCostArrangement(
+ availableSpace = carouselMainAxisSize,
+ targetSmallSize = targetSmallSize,
+ minSmallSize = minSmallSize,
+ maxSmallSize = maxSmallSize,
+ smallCounts = smallCounts,
+ targetMediumSize = targetMediumSize,
+ mediumCounts = mediumCounts,
+ targetLargeSize = targetLargeSize,
+ largeCounts = largeCounts,
+ )
+
+ return if (arrangement == null) {
+ null
+ } else {
+ createStartAlignedKeylineList(
+ carouselMainAxisSize = carouselMainAxisSize,
+ anchorSize = anchorSize,
+ arrangement = arrangement
+ )
+ }
+}
+
+internal fun createStartAlignedKeylineList(
+ carouselMainAxisSize: Float,
+ anchorSize: Float,
+ arrangement: Arrangement
+): KeylineList {
+ return keylineListOf(carouselMainAxisSize, CarouselAlignment.Start) {
+ add(anchorSize, isAnchor = true)
+
+ repeat(arrangement.largeCount) { add(arrangement.largeSize) }
+ repeat(arrangement.mediumCount) { add(arrangement.mediumSize) }
+ repeat(arrangement.smallCount) { add(arrangement.smallSize) }
+
+ add(anchorSize, isAnchor = true)
+ }
+}
+
+/**
+ * Creates a list of keylines that arranges items into the 'uncontained' configuration. This
+ * configuration lays out as many items as it can in the given item size without getting cut off,
+ * and with the remaining space adds a cut off item with size constraints to ensure enough motion
+ * when scrolling off-screen.
+ *
+ * For more information, see <a href="https://material.io/components/carousel/overview">design
+ * guidelines</a>.
+ *
+ * @param density The [Density] object that provides pixel density information of the device
+ * @param carouselMainAxisSize The carousel container's pixel size in the main scrolling axis
+ * @param itemSize the size of large items, in pixels, in the main scrolling axis
+ * @param itemSpacing the spacing between items in pixels
+ */
+internal fun uncontainedKeylineList(
+ density: Density,
+ carouselMainAxisSize: Float,
+ itemSize: Float,
+ itemSpacing: Float,
+): KeylineList? {
+ if (carouselMainAxisSize == 0f || itemSize == 0f) {
+ return null
+ }
+
+ val largeItemSize = min(itemSize + itemSpacing, carouselMainAxisSize)
+ // Calculate how much space there is remaining after squeezing in as many large items as we can.
+ val largeCount = max(1, floor(carouselMainAxisSize / largeItemSize).toInt())
+ val remainingSpace: Float = carouselMainAxisSize - largeCount * largeItemSize
+
+ val mediumCount = if (remainingSpace > 0) 1 else 0
+
+ val defaultAnchorSize = with(density) { StrategyDefaults.AnchorSize.toPx() }
+ val mediumItemSize = calculateMediumChildSize(
+ minimumMediumSize = defaultAnchorSize,
+ largeItemSize = largeItemSize,
+ remainingSpace = remainingSpace)
+ val arrangement = Arrangement(
+ 0,
+ 0F,
+ 0,
+ mediumItemSize,
+ mediumCount,
+ largeItemSize,
+ largeCount
+ )
+
+ val xSmallSize = min(defaultAnchorSize, itemSize)
+ // Make the anchor size half the cut off item size to make the motion at the left closer
+ // to the right where the cut off is.
+ val anchorSize: Float = max(xSmallSize, mediumItemSize * 0.5f)
+ return createStartAlignedKeylineList(
+ carouselMainAxisSize = carouselMainAxisSize,
+ anchorSize = anchorSize,
+ arrangement = arrangement)
+}
+
+/**
+ * Calculates a size of a medium item in the carousel that is not bigger than the large item
+ * size, and arbitrarily chooses a size small enough such that there is a size disparity between
+ * the medium and large sizes, but large enough to have a sufficient percentage cut off.
+ */
+private fun calculateMediumChildSize(
+ minimumMediumSize: Float,
+ largeItemSize: Float,
+ remainingSpace: Float
+): Float {
+ // With the remaining space, we want to add a 'medium' size item that gets sufficiently
+ // cut off. Ideally, it is large enough such that a third of the item is cut off, meaning
+ // that it is 1.5x the remaining space.
+ var mediumItemSize = minimumMediumSize
+ val sizeWithThirdCutOff = remainingSpace * 1.5f
+ mediumItemSize = max(sizeWithThirdCutOff, mediumItemSize)
+
+ // If the medium child is larger than the threshold percentage of the large child size,
+ // it's too similar and won't create sufficient motion when scrolling items between the large
+ // items and the medium item.
+ val largeItemThreshold: Float =
+ largeItemSize * StrategyDefaults.MediumLargeItemDiffThreshold
+ if (mediumItemSize > largeItemThreshold) {
+ // Choose whichever is bigger between the maximum threshold of the medium child size, or
+ // a size such that only 20% of the space is cut off.
+ val sizeWithFifthCutOff = remainingSpace * 1.2f
+ mediumItemSize = max(largeItemThreshold, sizeWithFifthCutOff)
+ }
+ return mediumItemSize
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt
index 8ca58e4..cf82756 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt
@@ -28,9 +28,10 @@
* Contains default values used across Strategies
*/
internal object StrategyDefaults {
- val minSmallSize = 40.dp
- val maxSmallSize = 56.dp
- val anchorSize = 10.dp
+ val MinSmallSize = 40.dp
+ val MaxSmallSize = 56.dp
+ val AnchorSize = 10.dp
+ const val MediumLargeItemDiffThreshold = 0.85f
}
/**
diff --git a/compose/runtime/runtime-livedata/build.gradle b/compose/runtime/runtime-livedata/build.gradle
index 1dcfaa9..50cb9c3 100644
--- a/compose/runtime/runtime-livedata/build.gradle
+++ b/compose/runtime/runtime-livedata/build.gradle
@@ -32,7 +32,6 @@
}
dependencies {
-
implementation(libs.kotlinStdlib)
api(project(":compose:runtime:runtime"))
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index bec84be..ea7cfa6 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -942,7 +942,7 @@
method public boolean addAll(java.util.Collection<? extends T> elements);
method public void clear();
method public boolean contains(T element);
- method public boolean containsAll(java.util.Collection<E> elements);
+ method public boolean containsAll(java.util.Collection<? extends T> elements);
method public T get(int index);
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public int getSize();
@@ -954,10 +954,10 @@
method public java.util.ListIterator<T> listIterator(int index);
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
method public boolean remove(T element);
- method public boolean removeAll(java.util.Collection<E> elements);
+ method public boolean removeAll(java.util.Collection<? extends T> elements);
method public T removeAt(int index);
method public void removeRange(int fromIndex, int toIndex);
- method public boolean retainAll(java.util.Collection<E> elements);
+ method public boolean retainAll(java.util.Collection<? extends T> elements);
method public T set(int index, T element);
method public java.util.List<T> subList(int fromIndex, int toIndex);
method public java.util.List<T> toList();
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index 64b6be9..5a5621f 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -992,7 +992,7 @@
method public boolean addAll(java.util.Collection<? extends T> elements);
method public void clear();
method public boolean contains(T element);
- method public boolean containsAll(java.util.Collection<E> elements);
+ method public boolean containsAll(java.util.Collection<? extends T> elements);
method public T get(int index);
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public int getSize();
@@ -1004,10 +1004,10 @@
method public java.util.ListIterator<T> listIterator(int index);
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
method public boolean remove(T element);
- method public boolean removeAll(java.util.Collection<E> elements);
+ method public boolean removeAll(java.util.Collection<? extends T> elements);
method public T removeAt(int index);
method public void removeRange(int fromIndex, int toIndex);
- method public boolean retainAll(java.util.Collection<E> elements);
+ method public boolean retainAll(java.util.Collection<? extends T> elements);
method public T set(int index, T element);
method public java.util.List<T> subList(int fromIndex, int toIndex);
method public java.util.List<T> toList();
diff --git a/compose/runtime/runtime/lint-baseline.xml b/compose/runtime/runtime/lint-baseline.xml
index 2fce8f0..f3284e9 100644
--- a/compose/runtime/runtime/lint-baseline.xml
+++ b/compose/runtime/runtime/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanSuppressTag"
@@ -66,24 +66,6 @@
<issue
id="PrimitiveInCollection"
- message="field groupInfos with type HashMap<Integer, GroupInfo>: replace with IntObjectMap"
- errorLine1=" private val groupInfos = run {"
- errorLine2=" ^">
- <location
- file="src/commonMain/kotlin/androidx/compose/runtime/Composer.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable result with type HashMap<Integer, GroupInfo>: replace with IntObjectMap"
- errorLine1=" val result = hashMapOf<Int, GroupInfo>()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/commonMain/kotlin/androidx/compose/runtime/Composer.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
message="field intParams with type List<IntParameter>: replace with IntList"
errorLine1=" val intParams = List(ints) { index -> IntParameter(index) }"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
index c1f4750..371faae 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
@@ -21,7 +21,6 @@
import androidx.collection.MutableScatterSet
import androidx.collection.mutableScatterSetOf
import androidx.compose.runtime.changelist.ChangeList
-import androidx.compose.runtime.collection.IdentityArraySet
import androidx.compose.runtime.collection.ScopeMap
import androidx.compose.runtime.collection.fastForEach
import androidx.compose.runtime.snapshots.ReaderKind
@@ -826,13 +825,7 @@
}
override fun observesAnyOf(values: Set<Any>): Boolean {
- if (values is IdentityArraySet<Any>) {
- values.fastForEach { value ->
- if (value in observations || value in derivedStates) return true
- }
- return false
- }
- for (value in values) {
+ values.fastForEach { value ->
if (value in observations || value in derivedStates) return true
}
return false
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
index 8ddff07..6a41089 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
@@ -16,10 +16,11 @@
package androidx.compose.runtime
+import androidx.collection.MutableScatterSet
import androidx.collection.mutableScatterSetOf
-import androidx.compose.runtime.collection.IdentityArraySet
import androidx.compose.runtime.collection.fastForEach
import androidx.compose.runtime.collection.mutableVectorOf
+import androidx.compose.runtime.collection.wrapIntoSet
import androidx.compose.runtime.external.kotlinx.collections.immutable.persistentSetOf
import androidx.compose.runtime.snapshots.MutableSnapshot
import androidx.compose.runtime.snapshots.ReaderKind
@@ -211,7 +212,7 @@
_knownCompositionsCache = newCache
newCache
}
- private var snapshotInvalidations = IdentityArraySet<Any>()
+ private var snapshotInvalidations = MutableScatterSet<Any>()
private val compositionInvalidations = mutableVectorOf<ControlledComposition>()
private val compositionsAwaitingApply = mutableListOf<ControlledComposition>()
private val compositionValuesAwaitingInsert = mutableListOf<MovableContentStateReference>()
@@ -299,7 +300,7 @@
private fun deriveStateLocked(): CancellableContinuation<Unit>? {
if (_state.value <= State.ShuttingDown) {
clearKnownCompositionsLocked()
- snapshotInvalidations = IdentityArraySet()
+ snapshotInvalidations = MutableScatterSet()
compositionInvalidations.clear()
compositionsAwaitingApply.clear()
compositionValuesAwaitingInsert.clear()
@@ -315,7 +316,7 @@
State.Inactive
}
runnerJob == null -> {
- snapshotInvalidations = IdentityArraySet()
+ snapshotInvalidations = MutableScatterSet()
compositionInvalidations.clear()
if (hasBroadcastFrameClockAwaitersLocked) State.InactivePendingWork
else State.Inactive
@@ -437,7 +438,8 @@
private fun recordComposerModifications(): Boolean {
val changes = synchronized(stateLock) {
if (snapshotInvalidations.isEmpty()) return hasFrameWorkLocked
- snapshotInvalidations.also { snapshotInvalidations = IdentityArraySet() }
+ snapshotInvalidations.wrapIntoSet()
+ .also { snapshotInvalidations = MutableScatterSet() }
}
val compositions = synchronized(stateLock) {
knownCompositions
@@ -453,7 +455,7 @@
if (_state.value <= State.ShuttingDown) return@run
}
}
- snapshotInvalidations = IdentityArraySet()
+ snapshotInvalidations = MutableScatterSet()
complete = true
} finally {
if (!complete) {
@@ -476,12 +478,12 @@
private inline fun recordComposerModifications(
onEachInvalidComposition: (ControlledComposition) -> Unit
) {
- val changes = snapshotInvalidations
+ val changes = snapshotInvalidations.wrapIntoSet()
if (changes.isNotEmpty()) {
knownCompositions.fastForEach { composition ->
composition.recordModificationsOf(changes)
}
- snapshotInvalidations = IdentityArraySet()
+ snapshotInvalidations = MutableScatterSet()
}
compositionInvalidations.forEach(onEachInvalidComposition)
compositionInvalidations.clear()
@@ -517,7 +519,8 @@
val toApply = mutableListOf<ControlledComposition>()
val toLateApply = mutableScatterSetOf<ControlledComposition>()
val toComplete = mutableScatterSetOf<ControlledComposition>()
- val modifiedValues = IdentityArraySet<Any>()
+ val modifiedValues = MutableScatterSet<Any>()
+ val modifiedValuesSet = modifiedValues.wrapIntoSet()
val alreadyComposed = mutableScatterSetOf<ControlledComposition>()
fun clearRecompositionState() {
@@ -623,7 +626,7 @@
knownCompositions.fastForEach { value ->
if (
value !in alreadyComposed &&
- value.observesAnyOf(modifiedValues)
+ value.observesAnyOf(modifiedValuesSet)
) {
toRecompose += value
}
@@ -741,7 +744,7 @@
compositionsAwaitingApply.clear()
compositionInvalidations.clear()
- snapshotInvalidations = IdentityArraySet()
+ snapshotInvalidations = MutableScatterSet()
compositionValuesAwaitingInsert.clear()
compositionValuesRemoved.clear()
@@ -941,7 +944,7 @@
}
// Perform recomposition for any invalidated composers
- val modifiedValues = IdentityArraySet<Any>()
+ val modifiedValues = MutableScatterSet<Any>()
try {
toRecompose.fastForEach { composer ->
performRecompose(composer, modifiedValues)?.let {
@@ -1175,7 +1178,7 @@
private fun performRecompose(
composition: ControlledComposition,
- modifiedValues: IdentityArraySet<Any>?
+ modifiedValues: MutableScatterSet<Any>?
): ControlledComposition? {
if (composition.isComposing ||
composition.isDisposed ||
@@ -1187,7 +1190,7 @@
// Record write performed by a previous composition as if they happened during
// composition.
composition.prepareCompose {
- modifiedValues.fastForEach { composition.recordWriteOf(it) }
+ modifiedValues.forEach { composition.recordWriteOf(it) }
}
}
composition.recompose()
@@ -1197,7 +1200,7 @@
private fun performInsertValues(
references: List<MovableContentStateReference>,
- modifiedValues: IdentityArraySet<Any>?
+ modifiedValues: MutableScatterSet<Any>?
): List<ControlledComposition> {
val tasks = references.fastGroupBy { it.composition }
for ((composition, refs) in tasks) {
@@ -1242,7 +1245,7 @@
private fun writeObserverOf(
composition: ControlledComposition,
- modifiedValues: IdentityArraySet<Any>?
+ modifiedValues: MutableScatterSet<Any>?
): (Any) -> Unit {
return { value ->
composition.recordWriteOf(value)
@@ -1252,7 +1255,7 @@
private inline fun <T> composing(
composition: ControlledComposition,
- modifiedValues: IdentityArraySet<Any>?,
+ modifiedValues: MutableScatterSet<Any>?,
block: () -> T
): T {
val snapshot = Snapshot.takeMutableSnapshot(
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
index 16cef80..ab0082f 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
@@ -364,6 +364,14 @@
val nearestScope = findEffectiveRecomposeScope(reader.currentGroup)
if (nearestScope != null) {
scopes.add(nearestScope)
+ if (nearestScope.anchor?.location == reader.currentGroup) {
+ // For the group that contains the restart group then, in some
+ // cases, such as when the parameter names of a function change,
+ // the restart lambda can be invalid if it is called. To avoid this
+ // the scope parent scope needs to be invalidated too.
+ val parentScope = findEffectiveRecomposeScope(reader.parent)
+ parentScope?.let { scopes.add(it) }
+ }
} else {
allScopesFound = false
scopes.clear()
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArraySet.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArraySet.kt
deleted file mode 100644
index 415a611..0000000
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/IdentityArraySet.kt
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.runtime.collection
-
-import androidx.compose.runtime.identityHashCode
-import kotlin.contracts.ExperimentalContracts
-import kotlin.contracts.contract
-
-/**
- * A set of values using an array as the backing store, ordered using [identityHashCode] for
- * both sorting and uniqueness.
- */
-@OptIn(ExperimentalContracts::class)
-internal class IdentityArraySet<T : Any> : Set<T> {
- override var size = 0
- private set
-
- var values: Array<Any?> = arrayOfNulls(16)
- private set
-
- /**
- * Returns true if the set contains [element]
- */
- override operator fun contains(element: T) = find(element) >= 0
-
- /**
- * Return the item at the given [index].
- */
- operator fun get(index: Int): T {
- checkIndexBounds(index)
-
- @Suppress("UNCHECKED_CAST")
- return values[index] as T
- }
-
- /**
- * Add [value] to the set and return `true` if it was added or `false` if it already existed.
- */
- fun add(value: T): Boolean {
- val index: Int
- val size = size
- val values = values
-
- if (size > 0) {
- index = find(value)
-
- if (index >= 0) {
- return false
- }
- } else {
- index = -1
- }
-
- val insertIndex = -(index + 1)
-
- if (size == values.size) {
- val newSorted = arrayOfNulls<Any>(values.size * 2)
- values.copyInto(
- destination = newSorted,
- destinationOffset = insertIndex + 1,
- startIndex = insertIndex,
- endIndex = size
- )
- values.copyInto(
- destination = newSorted,
- endIndex = insertIndex
- )
- this.values = newSorted
- } else {
- values.copyInto(
- destination = values,
- destinationOffset = insertIndex + 1,
- startIndex = insertIndex,
- endIndex = size
- )
- }
- this.values[insertIndex] = value
- this.size++
- return true
- }
-
- /**
- * Remove all values from the set.
- */
- fun clear() {
- values.fill(null)
- size = 0
- }
-
- /**
- * Call [block] for all items in the set.
- */
- inline fun fastForEach(block: (T) -> Unit) {
- contract { callsInPlace(block) }
- val values = values
- for (i in 0 until size) {
- @Suppress("UNCHECKED_CAST")
- block(values[i] as T)
- }
- }
-
- inline fun fastAny(block: (T) -> Boolean): Boolean {
- contract { callsInPlace(block) }
- val size = size
- if (size == 0) return false
- val values = values
- for (i in 0 until size) {
- @Suppress("UNCHECKED_CAST")
- if (block(values[i] as T)) return true
- }
- return false
- }
-
- fun addAll(collection: Collection<T>) {
- if (collection.isEmpty()) return
-
- if (collection !is IdentityArraySet<T>) {
- // Unknown collection, just add repeatedly
- for (value in collection) {
- add(value)
- }
- } else {
- // Identity set, merge sorted arrays
- val thisValues = values
- val otherValues = collection.values
- val thisSize = size
- val otherSize = collection.size
- val combinedSize = thisSize + otherSize
-
- val needsResize = values.size < combinedSize
- val elementsInOrder = thisSize == 0 ||
- identityHashCode(thisValues[thisSize - 1]) < identityHashCode(otherValues[0])
-
- if (!needsResize && elementsInOrder) {
- // fast path, just copy target values
- otherValues.copyInto(
- destination = thisValues,
- destinationOffset = thisSize,
- startIndex = 0,
- endIndex = otherSize
- )
- size += otherSize
- } else {
- // slow path, merge this and other values
- val newArray = if (needsResize) {
- arrayOfNulls(if (thisSize > otherSize) thisSize * 2 else otherSize * 2)
- } else {
- thisValues
- }
- var thisIndex = thisSize - 1
- var otherIndex = otherSize - 1
- var nextInsertIndex = combinedSize - 1
- while (thisIndex >= 0 || otherIndex >= 0) {
- val nextValue = when {
- thisIndex < 0 -> otherValues[otherIndex--]
- otherIndex < 0 -> thisValues[thisIndex--]
- else -> {
- val thisValue = thisValues[thisIndex]
- val otherValue = otherValues[otherIndex]
-
- val thisHash = identityHashCode(thisValue)
- val otherHash = identityHashCode(otherValue)
- when {
- thisHash > otherHash -> {
- thisIndex--
- thisValue
- }
- thisHash < otherHash -> {
- otherIndex--
- otherValue
- }
- thisValue === otherValue -> {
- // hash and the value are the same, advance both pointers
- thisIndex--
- otherIndex--
- thisValue
- }
- else -> {
- // collision, lookup if the same item is in the array
- var i = thisIndex - 1
- var foundDuplicate = false
- while (i >= 0) {
- val value = thisValues[i--]
- if (identityHashCode(value) != otherHash) break
- if (otherValue === value) {
- foundDuplicate = true
- break
- }
- }
-
- if (foundDuplicate) {
- // advance pointer and continue next iteration of outer
- // merge loop.
- otherIndex--
- continue
- } else {
- // didn't find the duplicate, put other item in array.
- otherIndex--
- otherValue
- }
- }
- }
- }
- }
-
- // insert value and continue
- newArray[nextInsertIndex--] = nextValue
- }
-
- if (nextInsertIndex >= 0) {
- // some values were duplicated, copy the merged part
- newArray.copyInto(
- newArray,
- destinationOffset = 0,
- startIndex = nextInsertIndex + 1,
- endIndex = combinedSize
- )
- }
- // newSize = endOffset - startOffset of copy above
- val newSize = combinedSize - (nextInsertIndex + 1)
- newArray.fill(null, fromIndex = newSize, toIndex = combinedSize)
-
- values = newArray
- size = newSize
- }
- }
- }
-
- /**
- * Return true if the set is empty.
- */
- override fun isEmpty() = size == 0
-
- /**
- * Returns true if the set is not empty.
- */
- fun isNotEmpty() = size > 0
-
- /**
- * Remove [value] from the set.
- */
- fun remove(value: T): Boolean {
- val index = find(value)
- val values = values
- val size = size
-
- if (index >= 0) {
- if (index < size - 1) {
- values.copyInto(
- destination = values,
- destinationOffset = index,
- startIndex = index + 1,
- endIndex = size
- )
- }
- values[size - 1] = null
- this.size--
- return true
- }
- return false
- }
-
- /**
- * Removes all values that match [predicate].
- */
- inline fun removeValueIf(predicate: (T) -> Boolean) {
- val values = values
- val size = size
-
- var destinationIndex = 0
- for (i in 0 until size) {
- @Suppress("UNCHECKED_CAST")
- val item = values[i] as T
- if (!predicate(item)) {
- if (destinationIndex != i) {
- values[destinationIndex] = item
- }
- destinationIndex++
- }
- }
- for (i in destinationIndex until size) {
- values[i] = null
- }
- this.size = destinationIndex
- }
-
- /**
- * Returns the index of [value] in the set or the negative index - 1 of the location where
- * it would have been if it had been in the set.
- */
- private fun find(value: Any?): Int {
- var low = 0
- var high = size - 1
- val valueIdentity = identityHashCode(value)
- val values = values
-
- while (low <= high) {
- val mid = (low + high).ushr(1)
- val midVal = values[mid]
- val midIdentity = identityHashCode(midVal)
- when {
- midIdentity < valueIdentity -> low = mid + 1
- midIdentity > valueIdentity -> high = mid - 1
- midVal === value -> return mid
- else -> return findExactIndex(mid, value, valueIdentity)
- }
- }
- return -(low + 1)
- }
-
- /**
- * When multiple items share the same [identityHashCode], then we must find the specific
- * index of the target item. This method assumes that [midIndex] has already been checked
- * for an exact match for [value], but will look at nearby values to find the exact item index.
- * If no match is found, the negative index - 1 of the position in which it would be will
- * be returned, which is always after the last item with the same [identityHashCode].
- */
- private fun findExactIndex(
- midIndex: Int,
- value: Any?,
- valueHash: Int
- ): Int {
- val values = values
- val size = size
-
- // hunt down first
- for (i in midIndex - 1 downTo 0) {
- val v = values[i]
- if (v === value) {
- return i
- }
- if (identityHashCode(v) != valueHash) {
- break // we've gone too far
- }
- }
-
- for (i in midIndex + 1 until size) {
- val v = values[i]
- if (v === value) {
- return i
- }
- if (identityHashCode(v) != valueHash) {
- // We've gone too far. We should insert here.
- return -(i + 1)
- }
- }
-
- // We should insert at the end
- return -(size + 1)
- }
-
- /**
- * Verifies if index is in bounds
- */
- private fun checkIndexBounds(index: Int) {
- if (index !in 0 until size) {
- throw IndexOutOfBoundsException("Index $index, size $size")
- }
- }
-
- /**
- * Return true if all elements of [elements] are in the set.
- */
- override fun containsAll(elements: Collection<T>) = elements.all { contains(it) }
-
- /**
- * Return an iterator for the set.
- */
- @Suppress("UNCHECKED_CAST")
- override fun iterator(): Iterator<T> = object : Iterator<T> {
- var index = 0
- override fun hasNext(): Boolean = index < size
- override fun next(): T = [email protected][index++] as T
- }
-
- override fun toString(): String {
- return joinToString(prefix = "[", postfix = "]") { it.toString() }
- }
-}
-
-internal inline fun <T : Any> Set<T>.fastForEach(block: (T) -> Unit) {
- if (this is IdentityArraySet<T>) {
- fastForEach(block)
- } else {
- forEach(block)
- }
-}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/ScatterSetWrapper.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/ScatterSetWrapper.kt
new file mode 100644
index 0000000..5854635
--- /dev/null
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/ScatterSetWrapper.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.compose.runtime.collection
+
+import androidx.collection.ScatterSet
+
+/**
+ * A wrapper for [ScatterSet] that implements [Set] APIs. This wrapper allows to use [ScatterSet]
+ * through external APIs and unwrap it back into [Set] for faster iteration / other operations.
+ */
+internal class ScatterSetWrapper<T>(
+ internal val set: ScatterSet<T>
+) : Set<T> {
+ override val size: Int
+ get() = set.size
+
+ override fun isEmpty(): Boolean = set.isEmpty()
+ override fun iterator(): Iterator<T> = iterator {
+ set.forEach {
+ yield(it)
+ }
+ }
+
+ override fun containsAll(elements: Collection<T>): Boolean =
+ elements.all { set.contains(it) }
+
+ override fun contains(element: T): Boolean =
+ set.contains(element)
+}
+
+internal fun <T> ScatterSet<T>.wrapIntoSet(): Set<T> = ScatterSetWrapper(this)
+
+internal inline fun <T : Any> Set<T>.fastForEach(block: (T) -> Unit) =
+ when (this) {
+ is ScatterSetWrapper<T> -> {
+ set.forEach(block)
+ }
+ else -> {
+ forEach(block)
+ }
+ }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
index d08defb..23e538b 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
@@ -16,6 +16,8 @@
package androidx.compose.runtime.snapshots
+import androidx.collection.MutableScatterSet
+import androidx.collection.mutableScatterSetOf
import androidx.compose.runtime.AtomicInt
import androidx.compose.runtime.AtomicReference
import androidx.compose.runtime.Composable
@@ -24,7 +26,7 @@
import androidx.compose.runtime.InternalComposeApi
import androidx.compose.runtime.SnapshotThreadLocal
import androidx.compose.runtime.checkPrecondition
-import androidx.compose.runtime.collection.IdentityArraySet
+import androidx.compose.runtime.collection.wrapIntoSet
import androidx.compose.runtime.currentThreadId
import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
import androidx.compose.runtime.requirePrecondition
@@ -227,7 +229,7 @@
/**
* The set of state objects that have been modified in this snapshot.
*/
- internal abstract val modified: IdentityArraySet<StateObject>?
+ internal abstract val modified: MutableScatterSet<StateObject>?
/**
* Notify the snapshot that all objects created in this snapshot to this point should be
@@ -816,7 +818,7 @@
) else null
var observers = emptyList<(Set<Any>, Snapshot) -> Unit>()
- var globalModified: IdentityArraySet<StateObject>? = null
+ var globalModified: MutableScatterSet<StateObject>? = null
sync {
validateOpen(this)
if (modified == null || modified.size == 0) {
@@ -824,7 +826,7 @@
val previousGlobalSnapshot = currentGlobalSnapshot.get()
takeNewGlobalSnapshot(previousGlobalSnapshot, emptyLambda)
val previousModified = previousGlobalSnapshot.modified
- if (!previousModified.isNullOrEmpty()) {
+ if (previousModified != null && previousModified.isNotEmpty()) {
observers = applyObservers
globalModified = previousModified
}
@@ -854,16 +856,19 @@
applied = true
// Notify any apply observers that changes applied were seen
- if (!globalModified.isNullOrEmpty()) {
- val nonNullGlobalModified = globalModified!!
- observers.fastForEach {
- it(nonNullGlobalModified, this)
+ if (globalModified != null) {
+ val nonNullGlobalModified = globalModified!!.wrapIntoSet()
+ if (nonNullGlobalModified.isNotEmpty()) {
+ observers.fastForEach {
+ it(nonNullGlobalModified, this)
+ }
}
}
- if (!modified.isNullOrEmpty()) {
+ if (modified != null && modified.isNotEmpty()) {
+ val modifiedSet = modified.wrapIntoSet()
observers.fastForEach {
- it(modified, this)
+ it(modifiedSet, this)
}
}
@@ -873,8 +878,8 @@
sync {
releasePinnedSnapshotsForCloseLocked()
checkAndOverwriteUnusedRecordsLocked()
- globalModified?.fastForEach { processForUnusedRecordsLocked(it) }
- modified?.fastForEach { processForUnusedRecordsLocked(it) }
+ globalModified?.forEach { processForUnusedRecordsLocked(it) }
+ modified?.forEach { processForUnusedRecordsLocked(it) }
merged?.fastForEach { processForUnusedRecordsLocked(it) }
merged = null
}
@@ -962,7 +967,7 @@
// id to be forgotten as no state records will refer to it.
this.modified = null
val id = id
- modified.fastForEach { state ->
+ modified.forEach { state ->
var current: StateRecord? = state.firstStateRecord
while (current != null) {
if (current.snapshotId == id || current.snapshotId in previousIds) {
@@ -997,12 +1002,12 @@
val start = this.invalid.set(id).or(this.previousIds)
val modified = modified!!
var statesToRemove: MutableList<StateObject>? = null
- modified.fastForEach { state ->
+ modified.forEach { state ->
val first = state.firstStateRecord
// If either current or previous cannot be calculated the object was created
// in a nested snapshot that was committed then changed.
- val current = readable(first, snapshotId, invalidSnapshots) ?: return@fastForEach
- val previous = readable(first, id, start) ?: return@fastForEach
+ val current = readable(first, snapshotId, invalidSnapshots) ?: return@forEach
+ val previous = readable(first, id, start) ?: return@forEach
if (current != previous) {
val applied = readable(first, id, this.invalid) ?: readError()
val merged = optimisticMerges?.get(current) ?: run {
@@ -1117,12 +1122,12 @@
}
override fun recordModified(state: StateObject) {
- (modified ?: IdentityArraySet<StateObject>().also { modified = it }).add(state)
+ (modified ?: mutableScatterSetOf<StateObject>().also { modified = it }).add(state)
}
override var writeCount: Int = 0
- override var modified: IdentityArraySet<StateObject>? = null
+ override var modified: MutableScatterSet<StateObject>? = null
internal var merged: List<StateObject>? = null
@@ -1324,7 +1329,7 @@
override fun hasPendingChanges(): Boolean = false
override val writeObserver: ((Any) -> Unit)? get() = null
- override var modified: IdentityArraySet<StateObject>?
+ override var modified: MutableScatterSet<StateObject>?
get() = null
@Suppress("UNUSED_PARAMETER")
set(value) = unsupported()
@@ -1395,7 +1400,7 @@
}
}
- override val modified: IdentityArraySet<StateObject>? get() = null
+ override val modified: MutableScatterSet<StateObject>? get() = null
override val writeObserver: ((Any) -> Unit)? get() = null
override fun recordModified(state: StateObject) = reportReadonlySnapshotWrite()
@@ -1594,7 +1599,7 @@
override fun hasPendingChanges(): Boolean = currentSnapshot.hasPendingChanges()
- override var modified: IdentityArraySet<StateObject>?
+ override var modified: MutableScatterSet<StateObject>?
get() = currentSnapshot.modified
@Suppress("UNUSED_PARAMETER")
set(value) = unsupported()
@@ -1706,7 +1711,7 @@
override fun hasPendingChanges(): Boolean = currentSnapshot.hasPendingChanges()
- override var modified: IdentityArraySet<StateObject>?
+ override var modified: MutableScatterSet<StateObject>?
get() = currentSnapshot.modified
@Suppress("UNUSED_PARAMETER")
set(value) = unsupported()
@@ -1895,7 +1900,7 @@
private fun <T> advanceGlobalSnapshot(block: (invalid: SnapshotIdSet) -> T): T {
var previousGlobalSnapshot = snapshotInitializer as GlobalSnapshot
- var modified: IdentityArraySet<StateObject>? = null // Effectively val; can be with contracts
+ var modified: MutableScatterSet<StateObject>? = null // Effectively val; can be with contracts
val result = sync {
previousGlobalSnapshot = currentGlobalSnapshot.get()
modified = previousGlobalSnapshot.modified
@@ -1911,7 +1916,7 @@
try {
val observers = applyObservers
observers.fastForEach { observer ->
- observer(it, previousGlobalSnapshot)
+ observer(it.wrapIntoSet(), previousGlobalSnapshot)
}
} finally {
pendingApplyObserverCount.add(-1)
@@ -1920,7 +1925,7 @@
sync {
checkAndOverwriteUnusedRecordsLocked()
- modified?.fastForEach { processForUnusedRecordsLocked(it) }
+ modified?.forEach { processForUnusedRecordsLocked(it) }
}
return result
@@ -2324,10 +2329,10 @@
if (modified == null) return null
val start = applyingSnapshot.invalid.set(applyingSnapshot.id).or(applyingSnapshot.previousIds)
var result: MutableMap<StateRecord, StateRecord>? = null
- modified.fastForEach { state ->
+ modified.forEach { state ->
val first = state.firstStateRecord
- val current = readable(first, id, invalidSnapshots) ?: return@fastForEach
- val previous = readable(first, id, start) ?: return@fastForEach
+ val current = readable(first, id, invalidSnapshots) ?: return@forEach
+ val previous = readable(first, id, start) ?: return@forEach
if (current != previous) {
// Try to produce a merged state record
val applied = readable(first, applyingSnapshot.id, applyingSnapshot.invalid)
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/collection/IdentityArraySetTest.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/collection/IdentityArraySetTest.kt
deleted file mode 100644
index f9e614a..0000000
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/collection/IdentityArraySetTest.kt
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.compose.runtime.collection
-
-import androidx.compose.runtime.identityHashCode
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertNotEquals
-import kotlin.test.assertNotNull
-import kotlin.test.assertNotSame
-import kotlin.test.assertNull
-import kotlin.test.assertTrue
-
-class IdentityArraySetTest {
- private val set: IdentityArraySet<Stuff> = IdentityArraySet()
-
- private val list = listOf(Stuff(10), Stuff(12), Stuff(1), Stuff(30), Stuff(10))
-
- @Test
- fun emptyConstruction() {
- val s = IdentityArraySet<Stuff>()
- assertEquals(0, s.size)
- }
-
- @Test
- fun get_indexWithinBounds_shouldNotThrow() {
- list.forEach { set.add(it) }
-
- assertNotNull(set.get(0))
- }
-
- @Test
- fun get_indexOutOfBounds_shouldThrow() {
- list.forEach { set.add(it) }
-
- // Index less than 0
- assertFailsWith<IndexOutOfBoundsException> {
- set.get(-1)
- }
-
- // Index greater than size
- assertFailsWith<IndexOutOfBoundsException> {
- set.get(list.size + 1)
- }
- }
-
- @Test
- fun addValueForward() {
- list.forEach { set.add(it) }
- assertEquals(list.size, set.size)
- var previousItem = set[0]
- for (i in 1 until set.size) {
- val item = set[i]
- assertTrue(identityHashCode(previousItem) < identityHashCode(item))
- previousItem = item
- }
- }
-
- @Test
- fun addValueReversed() {
- list.asReversed().forEach { set.add(it) }
- assertEquals(list.size, set.size)
- var previousItem = set[0]
- for (i in 1 until set.size) {
- val item = set[i]
- assertTrue(identityHashCode(previousItem) < identityHashCode(item))
- previousItem = item
- }
- }
-
- @Test
- fun addExistingValue() {
- list.forEach { set.add(it) }
- list.asReversed().forEach { set.add(it) }
-
- assertEquals(list.size, set.size)
- var previousItem = set[0]
- for (i in 1 until set.size) {
- val item = set[i]
- assertTrue(identityHashCode(previousItem) < identityHashCode(item))
- previousItem = item
- }
- }
-
- @Test
- fun clear() {
- list.forEach { set.add(it) }
- set.clear()
-
- assertEquals(0, set.size)
- set.values.forEach {
- assertNull(it)
- }
- }
-
- @Test
- fun remove() {
- list.forEach { set.add(it) }
-
- // remove a value that doesn't exist:
- val removed = set.remove(Stuff(10))
- assertEquals(list.size, set.size)
- assertFalse(removed)
-
- // remove a value in the middle:
- testRemoveValueAtIndex(set.size / 2)
-
- // remove the last value
- testRemoveValueAtIndex(set.size - 1)
-
- // remove a first value
- testRemoveValueAtIndex(0)
- }
-
- @Test
- fun removeValueIf() {
- list.forEach { set.add(it) }
-
- set.removeValueIf { it.item == 10 }
-
- // Make sure we've removed both items
- assertEquals(list.size - 2, set.size)
- set.fastForEach { assertNotEquals(10, it.item) }
- assertNull(set.values[set.size])
- assertNull(set.values[set.size + 1])
- }
-
- @Test
- fun growSet() {
- val verifierSet = mutableSetOf<Stuff>()
- repeat(100) {
- val stuff = Stuff(it)
- set.add(stuff)
- verifierSet.add(stuff)
- }
- assertEquals(100, set.size)
- set.fastForEach { verifierSet.remove(it) }
- assertEquals(0, verifierSet.size)
- }
-
- @Test
- fun canUseAsSetOfT() {
- val stuff = Array(100) { Stuff(it) }
- for (i in 0 until 100 step 2) {
- set.add(stuff[i])
- }
- val setOfT: Set<Stuff> = set
- for (i in 0 until 100) {
- val expected = i % 2 == 0
- if (expected) {
- assertTrue(stuff[i] in set)
- assertTrue(stuff[i] in setOfT)
- } else {
- assertFalse(stuff[i] in set)
- assertFalse(stuff[i] in setOfT)
- }
- }
- for (element in setOfT) {
- assertTrue(element.item % 2 == 0)
- assertEquals(element, stuff[element.item])
- }
-
- set.add(stuff[1])
- assertTrue(stuff[1] in setOfT)
-
- assertTrue(setOfT.containsAll(listOf(stuff[0], stuff[1], stuff[2])))
- }
-
- @Test
- fun addAll_Collection() {
- set.addAll(list)
-
- assertEquals(list.size, set.size)
- for (value in list) {
- assertTrue(value in set)
- }
- }
-
- @Test
- fun addAll_IdentityArraySet() {
- val anotherSet = IdentityArraySet<Stuff>()
- anotherSet.addAll(list)
-
- set.addAll(anotherSet)
-
- for (value in list) {
- assertTrue(value in set)
- }
-
- set.addAll(anotherSet)
-
- assertEquals(anotherSet.size, set.size)
- for (value in list) {
- assertTrue(value in set)
- }
-
- val stuff = Array(100) { Stuff(it) }
- for (i in 0 until 100 step 2) {
- anotherSet.add(stuff[i])
- }
- set.addAll(anotherSet)
-
- for (i in stuff.indices) {
- val value = stuff[i]
- if (i % 2 == 0) {
- assertTrue(value in set, "Expected to have element $i in $set")
- } else {
- assertFalse(value in set, "Didn't expect to have element $i in $set")
- }
- }
-
- for (value in list) {
- assertTrue(value in set)
- }
- }
-
- private fun testRemoveValueAtIndex(index: Int) {
- val value = set[index]
- val initialSize = set.size
- val removed = set.remove(value)
- assertEquals(initialSize - 1, set.size)
- assertTrue(removed)
- assertNull(set.values[set.size])
- set.fastForEach { assertNotSame(value, it) }
- }
-
- data class Stuff(val item: Int)
-}
diff --git a/compose/ui/ui-geometry/build.gradle b/compose/ui/ui-geometry/build.gradle
index 1d9fa6a..1d45f14 100644
--- a/compose/ui/ui-geometry/build.gradle
+++ b/compose/ui/ui-geometry/build.gradle
@@ -41,8 +41,7 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
-
- implementation("androidx.compose.runtime:runtime:1.2.1")
+ implementation("androidx.compose.runtime:runtime:1.6.0")
implementation(project(":compose:ui:ui-util"))
}
}
@@ -70,7 +69,6 @@
desktopMain {
dependsOn(jvmMain)
dependencies {
- implementation(project(":compose:runtime:runtime"))
}
}
diff --git a/compose/ui/ui-graphics/build.gradle b/compose/ui/ui-graphics/build.gradle
index 3f9cc28..a28e275 100644
--- a/compose/ui/ui-graphics/build.gradle
+++ b/compose/ui/ui-graphics/build.gradle
@@ -43,7 +43,7 @@
api(libs.androidx.annotation)
api(project(":compose:ui:ui-unit"))
- implementation(project(":compose:runtime:runtime"))
+ implementation("androidx.compose.runtime:runtime:1.6.0")
implementation(project(":compose:ui:ui-util"))
implementation("androidx.collection:collection:1.4.0")
}
@@ -59,7 +59,6 @@
dependsOn(commonMain)
dependencies {
api(libs.skikoCommon)
- implementation(project(":compose:runtime:runtime"))
}
}
@@ -73,7 +72,6 @@
dependsOn(jvmMain)
dependencies {
implementation("androidx.graphics:graphics-path:1.0.0-beta02")
- api(libs.androidx.annotation)
api("androidx.annotation:annotation-experimental:1.4.0")
}
}
diff --git a/compose/ui/ui-inspection/lint-baseline.xml b/compose/ui/ui-inspection/lint-baseline.xml
index a1c812d..ae2ee17 100644
--- a/compose/ui/ui-inspection/lint-baseline.xml
+++ b/compose/ui/ui-inspection/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="PrimitiveInCollection"
@@ -19,211 +19,4 @@
file="src/main/java/androidx/compose/ui/inspection/util/AnchorMap.kt"/>
</issue>
- <issue
- id="PrimitiveInCollection"
- message="field viewsToSkip with type List<Long>: replace with LongList"
- errorLine1=" val viewsToSkip: List<Long> ="
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/compose/AndroidComposeViewWrapper.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="return type List<Long> of getViewsToSkip: replace with LongList"
- errorLine1=" val viewsToSkip: List<Long> ="
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/compose/AndroidComposeViewWrapper.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="return type Map<Long, InspectorNode> of getLookup: replace with LongObjectMap"
- errorLine1=" val lookup: Map<Long, InspectorNode>"
- errorLine2=" ~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable var785951a with type Map<Long, ? extends InspectorNode>: replace with LongObjectMap"
- errorLine1=" get() = _lookup ?: trees.flatMap { it.nodes }"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field _lookup with type Map<Long, InspectorNode>: replace with LongObjectMap"
- errorLine1=" private var _lookup: Map<Long, InspectorNode>? = null"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="constructor CacheTree has parameter viewsToSkip with type List<Long>: replace with LongList"
- errorLine1=" val viewsToSkip: List<Long>"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field viewsToSkip with type List<Long>: replace with LongList"
- errorLine1=" val viewsToSkip: List<Long>"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="return type List<Long> of getViewsToSkip: replace with LongList"
- errorLine1=" val viewsToSkip: List<Long>"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field _cachedNodes with type Map<Long, CacheData>: replace with LongObjectMap"
- errorLine1=" private val _cachedNodes = mutableMapOf<Long, CacheData>()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="return type Map<Long, CacheData> of getCachedNodes: replace with LongObjectMap"
- errorLine1=" private val cachedNodes: MutableMap<Long, CacheData>"
- errorLine2=" ~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable data with type Map<Long, ? extends CacheData>: replace with LongObjectMap"
- errorLine1=" val data = ThreadUtils.runOnMainThread {"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable composeViewsByRoot with type Map<Long, ? extends List<? extends AndroidComposeViewWrapper>>: replace with LongObjectMap"
- errorLine1=" val composeViewsByRoot = composeViews.groupBy { it.rootView.uniqueDrawingId }"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable data with type Map<Long, ? extends CacheData>: replace with LongObjectMap"
- errorLine1=" val data = composeViewsByRoot.mapValues { (_, composeViews) ->"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/ComposeLayoutInspector.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="method asIntArray has parameter $this$asIntArray with type List<Integer>: replace with IntList"
- errorLine1="fun List<Int>.asIntArray() ="
- errorLine2=" ~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/util/IntArray.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field semanticsMap with type Map<Integer, List<RawParameter>>: replace with IntObjectMap"
- errorLine1=" /** Map from semantics id to a list of merged semantics information */"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field unmergedSemanticsMap with type Map<Integer, List<RawParameter>>: replace with IntObjectMap"
- errorLine1=" /* Map of seemantics id to a list of unmerged semantics information */"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field found with type Map<Long, InspectorNode>: replace with LongObjectMap"
- errorLine1=" /**"
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTree.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="constructor NodeParameterReference has parameter indices with type List<Integer>: replace with IntList"
- errorLine1=" indices: List<Int>"
- errorLine2=" ~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/NodeParameterReference.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field systemPackages with type Set<Integer>: replace with IntSet"
- errorLine1="val systemPackages = setOf("
- errorLine2="^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/PackageHashes.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="return type Set<Integer> of getSystemPackages: replace with IntSet"
- errorLine1="val systemPackages = setOf("
- errorLine2=" ~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/PackageHashes.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field valueIndex with type List<Integer>: replace with IntList"
- errorLine1=" private val valueIndex = mutableListOf<Int>()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field rootValueIndexCache with type Map<Long, IdentityHashMap<Object, NodeParameterReference>>: replace with LongObjectMap"
- errorLine1=" private val rootValueIndexCache ="
- errorLine2=" ^">
- <location
- file="src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="field innerMap with type Map<String, Integer>: replace with ObjectIntMap"
- errorLine1=" private val innerMap = mutableMapOf<String, Int>()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/compose/ui/inspection/proto/StringTable.kt"/>
- </issue>
-
</issues>
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt
index 450c74f..d3375b6 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/ParameterFactoryTest.kt
@@ -717,6 +717,7 @@
@Test
fun testWrappedModifier() {
+ @Suppress("DEPRECATION")
fun Modifier.frame(color: Color) = inspectable(
debugInspectorInfo {
name = "frame"
diff --git a/compose/ui/ui-test-junit4/build.gradle b/compose/ui/ui-test-junit4/build.gradle
index c41faf1..a7b8e52 100644
--- a/compose/ui/ui-test-junit4/build.gradle
+++ b/compose/ui/ui-test-junit4/build.gradle
@@ -62,16 +62,14 @@
}
}
-
androidMain {
dependsOn(jvmMain)
dependencies {
api("androidx.activity:activity:1.2.1")
- implementation "androidx.activity:activity-compose:1.3.0"
api("androidx.test.ext:junit:1.1.5")
- implementation("androidx.annotation:annotation:1.1.0")
-
- implementation(project(":compose:runtime:runtime-saveable"))
+ implementation("androidx.activity:activity-compose:1.3.0")
+ implementation("androidx.annotation:annotation:1.1.0")
+ implementation("androidx.compose.runtime:runtime-saveable:1.6.0")
implementation("androidx.lifecycle:lifecycle-common:2.5.1")
implementation("androidx.lifecycle:lifecycle-runtime:2.5.1")
implementation("androidx.test:core:1.5.0")
diff --git a/compose/ui/ui-test/build.gradle b/compose/ui/ui-test/build.gradle
index 18d3ea7..68eb8e6 100644
--- a/compose/ui/ui-test/build.gradle
+++ b/compose/ui/ui-test/build.gradle
@@ -42,7 +42,7 @@
api(project(":compose:ui:ui"))
api(project(":compose:ui:ui-text"))
api(project(":compose:ui:ui-unit"))
- api(project(":compose:runtime:runtime"))
+ api("androidx.compose.runtime:runtime:1.6.0")
api(libs.kotlinStdlib)
implementation(project(":compose:ui:ui-util"))
@@ -63,20 +63,17 @@
}
}
-
androidMain {
dependsOn(jvmMain)
dependencies {
- implementation "androidx.activity:activity-compose:1.3.0"
-
api(project(":compose:ui:ui-graphics"))
-
+ implementation("androidx.activity:activity-compose:1.3.0")
implementation("androidx.annotation:annotation:1.1.0")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.test.espresso:espresso-core:3.5.0")
implementation("androidx.test.espresso:espresso-idling-resource:3.5.0")
- implementation("androidx.test:monitor:1.6.1")
- }
+ implementation("androidx.test:monitor:1.6.1")
+ }
}
desktopMain {
diff --git a/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/GlobalAssertionsTest.kt b/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/GlobalAssertionsTest.kt
index 8f2a7d1..6b00a30 100644
--- a/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/GlobalAssertionsTest.kt
+++ b/compose/ui/ui-test/src/androidInstrumentedTest/kotlin/androidx/compose/ui/test/GlobalAssertionsTest.kt
@@ -37,41 +37,44 @@
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalTestApi::class)
class GlobalAssertionsTest {
- @get:Rule val composeTestRule = createComposeRule()
+ @get:Rule
+ val composeTestRule = createComposeRule()
- @Before fun setUp() {}
+ @Before
+ fun setUp() {
+ }
- @Test
- fun performClick_withGlobalAssertion_triggersGlobalAssertion() {
- composeTestRule.setContent { CountingButton() }
- var capturedSni: SemanticsNodeInteraction? = null
+ @Test
+ fun performClick_withGlobalAssertion_triggersGlobalAssertion() {
+ composeTestRule.setContent { CountingButton() }
+ var capturedSni: SemanticsNodeInteraction? = null
- addGlobalAssertion(/* name= */ "Fred") { sni -> capturedSni = sni }
- composeTestRule.onNodeWithText("Increment counter").performClick()
+ addGlobalAssertion(/* name= */ "Fred") { sni -> capturedSni = sni }
+ composeTestRule.onNodeWithText("Increment counter").performClick()
- composeTestRule.onNodeWithText("Clicks: 1").assertExists()
- capturedSni!!.assertTextContains("Increment counter")
- }
+ composeTestRule.onNodeWithText("Clicks: 1").assertExists()
+ capturedSni!!.assertTextContains("Increment counter")
+ }
- @Test
- fun performClick_withGlobalAssertionRemoved_doesNotTriggersGlobalAssertion() {
- composeTestRule.setContent { CountingButton() }
- var capturedSni: SemanticsNodeInteraction? = null
+ @Test
+ fun performClick_withGlobalAssertionRemoved_doesNotTriggersGlobalAssertion() {
+ composeTestRule.setContent { CountingButton() }
+ var capturedSni: SemanticsNodeInteraction? = null
- addGlobalAssertion(/* name= */ "Fred") { sni -> capturedSni = sni }
- removeGlobalAssertion(/* name= */ "Fred")
- composeTestRule.onNodeWithText("Increment counter").performClick()
+ addGlobalAssertion(/* name= */ "Fred") { sni -> capturedSni = sni }
+ removeGlobalAssertion(/* name= */ "Fred")
+ composeTestRule.onNodeWithText("Increment counter").performClick()
- composeTestRule.onNodeWithText("Clicks: 1").assertExists()
- assertThat(capturedSni).isNull()
- }
+ composeTestRule.onNodeWithText("Clicks: 1").assertExists()
+ assertThat(capturedSni).isNull()
+ }
}
@Composable
internal fun CountingButton() {
- var counter by remember { mutableStateOf(0) }
- Column {
- Button(onClick = { counter++ }) { Text("Increment counter") }
- Text(text = "Clicks: $counter")
- }
+ var counter by remember { mutableStateOf(0) }
+ Column {
+ Button(onClick = { counter++ }) { Text("Increment counter") }
+ Text(text = "Clicks: $counter")
+ }
}
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GlobalAssertions.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GlobalAssertions.kt
index 222a3e3..18ebb02 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GlobalAssertions.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/GlobalAssertions.kt
@@ -35,7 +35,7 @@
*/
@ExperimentalTestApi
fun addGlobalAssertion(name: String, assertion: (SemanticsNodeInteraction) -> Unit) {
- GlobalAssertionsCollection.put(name, assertion)
+ GlobalAssertionsCollection.put(name, assertion)
}
/**
@@ -45,7 +45,7 @@
*/
@ExperimentalTestApi
fun removeGlobalAssertion(name: String) {
- GlobalAssertionsCollection.remove(name)
+ GlobalAssertionsCollection.remove(name)
}
/**
@@ -56,8 +56,8 @@
*/
@ExperimentalTestApi
fun SemanticsNodeInteraction.invokeGlobalAssertions(): SemanticsNodeInteraction {
- GlobalAssertionsCollection.invoke(this)
- return this
+ GlobalAssertionsCollection.invoke(this)
+ return this
}
/**
@@ -69,37 +69,37 @@
@ExperimentalTestApi
fun SemanticsNodeInteractionCollection.invokeGlobalAssertions():
SemanticsNodeInteractionCollection {
- GlobalAssertionsCollection.invoke(this)
- return this
+ GlobalAssertionsCollection.invoke(this)
+ return this
}
/** Assertions intended to be executed before test actions. */
internal object GlobalAssertionsCollection {
- const val TAG = "GlobalAssertions"
+ const val TAG = "GlobalAssertions"
- /** Map of assertion names to their functions */
- private val globalAssertions = mutableMapOf<String, (SemanticsNodeInteraction) -> Unit>()
+ /** Map of assertion names to their functions */
+ private val globalAssertions = mutableMapOf<String, (SemanticsNodeInteraction) -> Unit>()
- /** Implementation of [addGlobalAssertion] */
- internal fun put(name: String, assertion: (SemanticsNodeInteraction) -> Unit) {
- globalAssertions[name] = assertion
- }
-
- /** Implementation of [removeGlobalAssertion] */
- internal fun remove(name: String) {
- globalAssertions.remove(name)
- }
-
- /** Executes every assertion on the given node. */
- internal fun invoke(sni: SemanticsNodeInteraction) {
- for (entry in globalAssertions.entries) {
- printToLog(TAG, "Executing \"${entry.key}\"")
- entry.value.invoke(sni)
+ /** Implementation of [addGlobalAssertion] */
+ internal fun put(name: String, assertion: (SemanticsNodeInteraction) -> Unit) {
+ globalAssertions[name] = assertion
}
- }
- /** Executes every assertion on the first node of the given collection. */
- internal fun invoke(snic: SemanticsNodeInteractionCollection) {
- invoke(snic.onFirst())
- }
+ /** Implementation of [removeGlobalAssertion] */
+ internal fun remove(name: String) {
+ globalAssertions.remove(name)
+ }
+
+ /** Executes every assertion on the given node. */
+ internal fun invoke(sni: SemanticsNodeInteraction) {
+ for (entry in globalAssertions.entries) {
+ printToLog(TAG, "Executing \"${entry.key}\"")
+ entry.value.invoke(sni)
+ }
+ }
+
+ /** Executes every assertion on the first node of the given collection. */
+ internal fun invoke(snic: SemanticsNodeInteractionCollection) {
+ invoke(snic.onFirst())
+ }
}
diff --git a/compose/ui/ui-text-google-fonts/build.gradle b/compose/ui/ui-text-google-fonts/build.gradle
index ce24693..1c199e3 100644
--- a/compose/ui/ui-text-google-fonts/build.gradle
+++ b/compose/ui/ui-text-google-fonts/build.gradle
@@ -32,9 +32,7 @@
}
dependencies {
-
implementation(libs.kotlinStdlib)
-
implementation("androidx.compose.runtime:runtime:1.2.1")
implementation(project(":compose:ui:ui-text"))
implementation("androidx.core:core:1.8.0")
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index 20df631..c01ca7d 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -1286,7 +1286,7 @@
ctor public LocaleList(String languageTags);
ctor public LocaleList(java.util.List<androidx.compose.ui.text.intl.Locale> localeList);
method public operator boolean contains(androidx.compose.ui.text.intl.Locale element);
- method public boolean containsAll(java.util.Collection<E> elements);
+ method public boolean containsAll(java.util.Collection<? extends androidx.compose.ui.text.intl.Locale> elements);
method public operator androidx.compose.ui.text.intl.Locale get(int i);
method public java.util.List<androidx.compose.ui.text.intl.Locale> getLocaleList();
method public int getSize();
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index bd6ae2a..00b4928 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -1286,7 +1286,7 @@
ctor public LocaleList(String languageTags);
ctor public LocaleList(java.util.List<androidx.compose.ui.text.intl.Locale> localeList);
method public operator boolean contains(androidx.compose.ui.text.intl.Locale element);
- method public boolean containsAll(java.util.Collection<E> elements);
+ method public boolean containsAll(java.util.Collection<? extends androidx.compose.ui.text.intl.Locale> elements);
method public operator androidx.compose.ui.text.intl.Locale get(int i);
method public java.util.List<androidx.compose.ui.text.intl.Locale> getLocaleList();
method public int getSize();
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index 0eeb331..6641935 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -47,8 +47,8 @@
api(project(":compose:ui:ui-unit"))
// when updating the runtime version please also update the runtime-saveable version
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:runtime:runtime-saveable"))
+ implementation("androidx.compose.runtime:runtime:1.6.0")
+ implementation("androidx.compose.runtime:runtime-saveable:1.6.0")
implementation(project(":compose:ui:ui-util"))
}
@@ -63,8 +63,6 @@
dependsOn(commonMain)
dependencies {
api(libs.skikoCommon)
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:runtime:runtime-saveable"))
}
}
@@ -75,7 +73,6 @@
}
}
-
androidMain {
dependsOn(commonMain)
dependsOn(jvmMain)
diff --git a/compose/ui/ui-tooling-data/build.gradle b/compose/ui/ui-tooling-data/build.gradle
index 1f20915..ad21576 100644
--- a/compose/ui/ui-tooling-data/build.gradle
+++ b/compose/ui/ui-tooling-data/build.gradle
@@ -41,7 +41,7 @@
dependencies {
implementation(libs.kotlinStdlib)
- api(project(":compose:runtime:runtime"))
+ api("androidx.compose.runtime:runtime:1.6.0")
api(project(":compose:ui:ui"))
}
}
@@ -62,7 +62,6 @@
skikoMain {
dependsOn(commonMain)
dependencies {
-
}
}
diff --git a/compose/ui/ui-tooling-preview/build.gradle b/compose/ui/ui-tooling-preview/build.gradle
index 0b81b0c..e48247e 100644
--- a/compose/ui/ui-tooling-preview/build.gradle
+++ b/compose/ui/ui-tooling-preview/build.gradle
@@ -40,7 +40,7 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
- api(project(":compose:runtime:runtime"))
+ api("androidx.compose.runtime:runtime:1.6.0")
}
}
@@ -58,7 +58,6 @@
skikoMain {
dependsOn(commonMain)
dependencies {
- api(project(":compose:runtime:runtime"))
}
}
@@ -73,7 +72,6 @@
dependsOn(skikoMain)
dependsOn(jvmMain)
dependencies {
-
}
}
diff --git a/compose/ui/ui-tooling/build.gradle b/compose/ui/ui-tooling/build.gradle
index 682722e..a8680ca 100644
--- a/compose/ui/ui-tooling/build.gradle
+++ b/compose/ui/ui-tooling/build.gradle
@@ -40,8 +40,8 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
+ api("androidx.compose.runtime:runtime:1.6.0")
api(project(":compose:ui:ui-tooling-preview"))
- api(project(":compose:runtime:runtime"))
api(project(":compose:ui:ui"))
api(project(":compose:ui:ui-tooling-data"))
}
@@ -49,7 +49,6 @@
commonTest {
dependencies {
-
}
}
diff --git a/compose/ui/ui-unit/build.gradle b/compose/ui/ui-unit/build.gradle
index b5946c7..7338576 100644
--- a/compose/ui/ui-unit/build.gradle
+++ b/compose/ui/ui-unit/build.gradle
@@ -40,12 +40,11 @@
commonMain {
dependencies {
implementation(libs.kotlinStdlibCommon)
- api(project(":compose:ui:ui-geometry"))
-
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:ui:ui-util"))
- implementation("androidx.collection:collection:1.4.0")
api("androidx.annotation:annotation:1.1.0")
+ api(project(":compose:ui:ui-geometry"))
+ implementation("androidx.collection:collection:1.4.0")
+ implementation("androidx.compose.runtime:runtime:1.6.0")
+ implementation(project(":compose:ui:ui-util"))
}
}
@@ -75,7 +74,6 @@
desktopMain {
dependsOn(jvmMain)
dependencies {
- implementation(project(":compose:runtime:runtime"))
}
}
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index ee3b92f..47724d2 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -2925,7 +2925,7 @@
public final class InspectableValueKt {
method public static inline kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> debugInspectorInfo(kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> definitions);
method public static kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> getNoInspectorInfo();
- method public static inline androidx.compose.ui.Modifier inspectable(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+ method @Deprecated public static inline androidx.compose.ui.Modifier inspectable(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
method public static boolean isDebugInspectorInfoEnabled();
method public static void setDebugInspectorInfoEnabled(boolean);
property public static final kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> NoInspectorInfo;
@@ -3665,6 +3665,7 @@
ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled);
ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled, optional boolean usePlatformDefaultWidth);
ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional boolean clippingEnabled);
+ ctor public PopupProperties(int flags, optional boolean inheritSecurePolicy, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional boolean excludeFromSystemGesture, optional boolean usePlatformDefaultWidth);
method public boolean getClippingEnabled();
method public boolean getDismissOnBackPress();
method public boolean getDismissOnClickOutside();
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 7ede5b9..6a2c2fc 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -2978,7 +2978,7 @@
public final class InspectableValueKt {
method public static inline kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> debugInspectorInfo(kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> definitions);
method public static kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> getNoInspectorInfo();
- method public static inline androidx.compose.ui.Modifier inspectable(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+ method @Deprecated public static inline androidx.compose.ui.Modifier inspectable(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
method @kotlin.PublishedApi internal static androidx.compose.ui.Modifier inspectableWrapper(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, androidx.compose.ui.Modifier wrapped);
method public static boolean isDebugInspectorInfoEnabled();
method public static void setDebugInspectorInfoEnabled(boolean);
@@ -3725,6 +3725,7 @@
ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled);
ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled, optional boolean usePlatformDefaultWidth);
ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional boolean clippingEnabled);
+ ctor public PopupProperties(int flags, optional boolean inheritSecurePolicy, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional boolean excludeFromSystemGesture, optional boolean usePlatformDefaultWidth);
method public boolean getClippingEnabled();
method public boolean getDismissOnBackPress();
method public boolean getDismissOnClickOutside();
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt
new file mode 100644
index 0000000..2f557b3
--- /dev/null
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/NestedScrollingBenchmark.kt
@@ -0,0 +1,158 @@
+/*
+ * 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.compose.ui.benchmark
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.ToggleableTestCase
+import androidx.compose.testutils.assertNoPendingChanges
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.doFramesUntilNoChangesPending
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
+import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.unit.Velocity
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
+import kotlinx.coroutines.runBlocking
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class NestedScrollingBenchmark {
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val nestedScrollingCaseFactory = { NestedScrollingTestCase() }
+
+ @Test
+ fun nested_scroll_propagation() {
+ benchmarkRule.runBenchmarkFor(nestedScrollingCaseFactory) {
+ runOnUiThread {
+ doFramesUntilNoChangesPending()
+ }
+
+ benchmarkRule.measureRepeatedOnUiThread {
+ getTestCase().toggleState()
+ runWithTimingDisabled {
+ assertNoPendingChanges()
+ getTestCase().assertPostToggle()
+ }
+ }
+ }
+ }
+}
+
+class NestedScrollingTestCase : LayeredComposeTestCase(), ToggleableTestCase {
+ private var collectedDeltasOuter = Offset.Zero
+ private var collectedDeltasMiddle = Offset.Zero
+ private var collectedVelocityOuter = Velocity.Zero
+ private var collectedVelocityMiddle = Velocity.Zero
+
+ private val outerConnection = object : NestedScrollConnection {
+ override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+ collectedDeltasOuter += available
+ return super.onPreScroll(available, source)
+ }
+
+ override suspend fun onPreFling(available: Velocity): Velocity {
+ collectedVelocityOuter += available
+ return super.onPreFling(available)
+ }
+ }
+
+ private val middleConnection = object : NestedScrollConnection {
+ override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+ collectedDeltasMiddle += available
+ return super.onPreScroll(available, source)
+ }
+
+ override suspend fun onPreFling(available: Velocity): Velocity {
+ collectedVelocityMiddle += available
+ return super.onPreFling(available)
+ }
+ }
+
+ private val dispatcher = NestedScrollDispatcher()
+ private val noOpConnection = object : NestedScrollConnection {}
+ private val delta = Offset(200f, 200f)
+ private val velocity = Velocity(2000f, 200f)
+ private var scrollResult = Offset.Zero
+ private var velocityResult = Velocity.Zero
+ private val IntermediateConnection = object : NestedScrollConnection {}
+
+ @Composable
+ override fun MeasuredContent() {
+ Box(
+ modifier = Modifier
+ .nestedScroll(outerConnection)
+ ) {
+ Box(
+ modifier = Modifier
+ .nestedScroll(middleConnection)
+ ) {
+ NestedBox(boxLevel = 20) {
+ Box(
+ modifier = Modifier
+ .nestedScroll(noOpConnection, dispatcher)
+ )
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun NestedBox(boxLevel: Int, leafContent: @Composable () -> Unit) {
+ if (boxLevel == 0) {
+ Box {
+ leafContent()
+ }
+ return
+ }
+
+ Box(modifier = Modifier.nestedScroll(IntermediateConnection)) {
+ NestedBox(boxLevel = boxLevel - 1, leafContent)
+ }
+ }
+
+ override fun toggleState() {
+ scrollResult = dispatcher.dispatchPreScroll(delta, NestedScrollSource.Drag)
+ scrollResult = dispatcher.dispatchPostScroll(delta, scrollResult, NestedScrollSource.Drag)
+
+ runBlocking {
+ velocityResult = dispatcher.dispatchPreFling(velocity)
+ velocityResult = dispatcher.dispatchPostFling(velocity, velocityResult)
+ }
+ }
+
+ fun assertPostToggle() {
+ assert(collectedDeltasOuter != Offset.Zero)
+ assert(collectedDeltasMiddle != Offset.Zero)
+ assert(collectedVelocityOuter != Velocity.Zero)
+ assert(collectedVelocityMiddle != Velocity.Zero)
+
+ assert(collectedDeltasOuter == scrollResult)
+ assert(collectedVelocityOuter == velocityResult)
+ }
+}
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 51c3e1d..4fcc01b 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -47,14 +47,14 @@
implementation("androidx.collection:collection:1.4.0")
implementation(project(":lifecycle:lifecycle-runtime"))
// when updating the runtime version please also update the runtime-saveable version
- implementation(project(":compose:runtime:runtime"))
- api(project(":compose:runtime:runtime-saveable"))
+ implementation("androidx.compose.runtime:runtime:1.6.0")
+ api("androidx.compose.runtime:runtime-saveable:1.6.0")
- api project(":compose:ui:ui-geometry")
- api project(":compose:ui:ui-graphics")
- api project(":compose:ui:ui-text")
- api project(":compose:ui:ui-unit")
- api project(":compose:ui:ui-util")
+ api(project(":compose:ui:ui-geometry"))
+ api(project(":compose:ui:ui-graphics"))
+ api(project(":compose:ui:ui-text"))
+ api(project(":compose:ui:ui-unit"))
+ api(project(":compose:ui:ui-util"))
}
}
@@ -74,7 +74,6 @@
skikoMain {
dependsOn(commonMain)
dependencies {
- api(project(":compose:ui:ui-graphics"))
api(libs.skikoCommon)
}
}
@@ -108,7 +107,6 @@
dependsOn(jvmMain)
dependencies {
implementation(libs.kotlinStdlib)
- implementation(libs.kotlinStdlibJdk8)
api(libs.kotlinCoroutinesSwing)
}
}
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/PointerInputInteropComposeInAndroid.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/PointerInputInteropComposeInAndroid.kt
index 39495d1..5d357f3 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/PointerInputInteropComposeInAndroid.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/PointerInputInteropComposeInAndroid.kt
@@ -232,20 +232,16 @@
myContext = peekAvailableContext()!!
- findViewById<TextView>(R.id.text1).text =
- "Demonstrates correct interop with simple tapping and a window manager"
- findViewById<TextView>(R.id.text2).text =
- "The top/outer text and button are Android, and the button dynamically triggers " +
- "adding/removing a ComposeView via the WindowManager. The inner ComposeView also " +
- "contains a button that tracks the number of clicks."
-
button = findViewById<Button>(R.id.button)
button.setOnClickListener {
- viewLoaded = if (viewLoaded != null) {
- myContext.removeWindow(viewLoaded!!)
- null
+ if (viewLoaded == null) {
+ viewLoaded = myContext.addWindow()
} else {
- myContext.addWindow()
+ if (viewLoaded!!.isAttachedToWindow) {
+ myContext.removeWindow(viewLoaded!!)
+ } else {
+ myContext.addWindow(viewLoaded)
+ }
}
}
}
@@ -280,7 +276,9 @@
get() = mViewModelStore
}
-private fun Context.buildWindowView(content: @Composable (composeView: View) -> Unit): View {
+private fun Context.buildWindowView(
+ content: @Composable (composeView: View) -> Unit
+): View {
val lifecycleOwner = ComposeViewLifecycleOwner()
lifecycleOwner.performRestore(null)
@@ -307,9 +305,11 @@
}
}
-private fun Context.addWindow(): View {
+private fun Context.addWindow(passedView: View? = null): View {
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
- val view = buildWindowView { SimpleClickableButton() }
+
+ // Reuse existing view (otherwise, create a new one).
+ val view = passedView ?: buildWindowView { SimpleClickableButton() }
val layoutParas = WindowManager.LayoutParams()
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/res/layout/compose_in_android_tap_reload.xml b/compose/ui/ui/integration-tests/ui-demos/src/main/res/layout/compose_in_android_tap_reload.xml
index 6d4d50a..724c966 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/res/layout/compose_in_android_tap_reload.xml
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/res/layout/compose_in_android_tap_reload.xml
@@ -16,24 +16,29 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:padding="15.dp">
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="0"/>
+ android:layout_weight="0"
+ android:text="@string/compose_in_android_dynamically_loading_compose_using_window_manager_title"/>
<TextView
android:id="@+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="0"/>
+ android:layout_weight="0"
+ android:text="@string/compose_in_android_dynamically_loading_compose_using_window_manager_details"/>
<Button
android:id="@+id/button"
- android:text="Click to unload/load ComposeView"
+ android:text="@string/compose_in_android_dynamically_loading_compose_using_window_manager_button_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="0"/>
+ android:layout_weight="0"
+ android:paddingEnd="10.dp"/>
+
</LinearLayout>
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/res/values/strings.xml b/compose/ui/ui/integration-tests/ui-demos/src/main/res/values/strings.xml
new file mode 100644
index 0000000..fdf9cc5
--- /dev/null
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?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.
+ -->
+
+<resources>
+ <string name="compose_in_android_dynamically_loading_compose_using_window_manager_details">The top/outer text and button are Views. The button adds/removes a ComposeView via the WindowManager. The inner ComposeView also contains a button that tracks the number of clicks.</string>
+ <string name="compose_in_android_dynamically_loading_compose_using_window_manager_title">Demonstrates interop with simple tapping and a window manager</string>
+ <string name="compose_in_android_dynamically_loading_compose_using_window_manager_button_text">Click to unload/load ComposeView</string>
+</resources>
\ No newline at end of file
diff --git a/compose/ui/ui/lint-baseline.xml b/compose/ui/ui/lint-baseline.xml
index a00bbef..4769573 100644
--- a/compose/ui/ui/lint-baseline.xml
+++ b/compose/ui/ui/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanThreadSleep"
@@ -93,15 +93,6 @@
<issue
id="PrimitiveInCollection"
- message="field alignmentLines with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
- errorLine1=" override val alignmentLines = alignmentLines"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/commonMain/kotlin/androidx/compose/ui/layout/IntermediateLayoutModifierNode.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
message="field alignmentLineMap with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
errorLine1=" private val alignmentLineMap: MutableMap<AlignmentLine, Int> = hashMapOf()"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -183,33 +174,6 @@
<issue
id="PrimitiveInCollection"
- message="field alignmentLines with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
- errorLine1=" override val alignmentLines = alignmentLines"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable oldLines with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
- errorLine1=" val oldLines = oldAlignmentLines"
- errorLine2=" ^">
- <location
- file="src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
- message="variable var43bc2abb with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
- errorLine1=" val oldLines = oldAlignmentLines"
- errorLine2=" ^">
- <location
- file="src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt"/>
- </issue>
-
- <issue
- id="PrimitiveInCollection"
message="field oldAlignmentLines with type Map<AlignmentLine, Integer>: replace with ObjectIntMap"
errorLine1=" private var oldAlignmentLines: MutableMap<AlignmentLine, Int>? = null"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/InspectableModifierSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/InspectableModifierSample.kt
index f0654e5..52df79c 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/InspectableModifierSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/InspectableModifierSample.kt
@@ -29,6 +29,7 @@
@Sampled
@Composable
+@Suppress("DEPRECATION")
fun InspectableModifierSample() {
/**
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
index d53a555..74e3bdc 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
@@ -1385,6 +1385,167 @@
assertTrue(totalEventLatch.await(1, TimeUnit.SECONDS))
}
+ /*
+ * Tests that a bad ACTION_HOVER_EXIT MotionEvent is ignored in Compose when it directly
+ * proceeds an ACTION_SCROLL MotionEvent. This happens in some versions of Android Studio when
+ * mirroring is used (b/314269723).
+ *
+ * The event order of MotionEvents:
+ * - Hover enter on box 1
+ * - Hover exit on box 1 (bad event)
+ * - Scroll on box 1
+ */
+ @Test
+ fun scrollMotionEvent_proceededImmediatelyByHoverExit_shouldNotTriggerHoverExit() {
+ // --> Arrange
+ val scrollDelta = Offset(0.35f, 0.65f)
+ var box1LayoutCoordinates: LayoutCoordinates? = null
+
+ val setUpFinishedLatch = CountDownLatch(4)
+
+ // Events for Box 1
+ var enterBox1 = false
+ var scrollBox1 = false
+
+ // All other events that should never be triggered in this test
+ var eventsThatShouldNotTrigger = false
+
+ var pointerEvent: PointerEvent? = null
+
+ rule.runOnUiThread {
+ container.setContent {
+ Column(
+ Modifier
+ .fillMaxSize()
+ .onGloballyPositioned {
+ setUpFinishedLatch.countDown()
+ }
+ ) {
+ // Box 1
+ Box(
+ Modifier
+ .size(50.dp)
+ .onGloballyPositioned {
+ box1LayoutCoordinates = it
+ setUpFinishedLatch.countDown()
+ }
+ .pointerInput(Unit) {
+ awaitPointerEventScope {
+ while (true) {
+ pointerEvent = awaitPointerEvent()
+
+ when (pointerEvent!!.type) {
+ PointerEventType.Enter -> {
+ enterBox1 = true
+ }
+
+ PointerEventType.Exit -> {
+ enterBox1 = false
+ }
+
+ PointerEventType.Scroll -> {
+ scrollBox1 = true
+ }
+
+ else -> {
+ eventsThatShouldNotTrigger = true
+ }
+ }
+ }
+ }
+ }
+ ) { }
+
+ // Box 2
+ Box(
+ Modifier
+ .size(50.dp)
+ .onGloballyPositioned {
+ setUpFinishedLatch.countDown()
+ }
+ .pointerInput(Unit) {
+ awaitPointerEventScope {
+ while (true) {
+ pointerEvent = awaitPointerEvent()
+ // Should never do anything with this UI element.
+ eventsThatShouldNotTrigger = true
+ }
+ }
+ }
+ ) { }
+
+ // Box 3
+ Box(
+ Modifier
+ .size(50.dp)
+ .onGloballyPositioned {
+ setUpFinishedLatch.countDown()
+ }
+ .pointerInput(Unit) {
+ awaitPointerEventScope {
+ while (true) {
+ pointerEvent = awaitPointerEvent()
+ // Should never do anything with this UI element.
+ eventsThatShouldNotTrigger = true
+ }
+ }
+ }
+ ) { }
+ }
+ }
+ }
+ // Ensure Arrange (setup) step is finished
+ assertTrue(setUpFinishedLatch.await(2, TimeUnit.SECONDS))
+
+ // --> Act + Assert (interwoven)
+ // Hover Enter on Box 1
+ dispatchMouseEvent(ACTION_HOVER_ENTER, box1LayoutCoordinates!!)
+ rule.runOnUiThread {
+ assertThat(enterBox1).isTrue()
+ assertThat(pointerEvent).isNotNull()
+ assertThat(eventsThatShouldNotTrigger).isFalse()
+ assertHoverEvent(pointerEvent!!, isEnter = true)
+ }
+
+ // We do not use dispatchMouseEvent() to dispatch the following two events, because the
+ // actions need to be executed in immediate succession
+ rule.runOnUiThread {
+ val root = box1LayoutCoordinates!!.findRootCoordinates()
+ val pos = root.localPositionOf(box1LayoutCoordinates!!, Offset.Zero)
+
+ // Bad hover exit event on Box 1
+ val exitMotionEvent = MotionEvent(
+ 0,
+ ACTION_HOVER_EXIT,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0).also { it.toolType = MotionEvent.TOOL_TYPE_MOUSE }),
+ arrayOf(PointerCoords(pos.x, pos.y, Offset.Zero.x, Offset.Zero.y))
+ )
+
+ // Main scroll event on Box 1
+ val scrollMotionEvent = MotionEvent(
+ 0,
+ ACTION_SCROLL,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0).also { it.toolType = MotionEvent.TOOL_TYPE_MOUSE }),
+ arrayOf(PointerCoords(pos.x, pos.y, scrollDelta.x, scrollDelta.y))
+ )
+
+ val androidComposeView = findAndroidComposeView(container) as AndroidComposeView
+ androidComposeView.dispatchHoverEvent(exitMotionEvent)
+ androidComposeView.dispatchGenericMotionEvent(scrollMotionEvent)
+ }
+
+ rule.runOnUiThread {
+ assertThat(enterBox1).isTrue()
+ assertThat(scrollBox1).isTrue()
+ assertThat(pointerEvent).isNotNull()
+ assertThat(eventsThatShouldNotTrigger).isFalse()
+ }
+ }
+
@Test
fun dispatchHoverMove() {
var layoutCoordinates: LayoutCoordinates? = null
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/InspectableValueTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/InspectableValueTest.kt
index 802339d..1cf6d5c 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/InspectableValueTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/platform/InspectableValueTest.kt
@@ -45,6 +45,7 @@
isDebugInspectorInfoEnabled = false
}
+ @Suppress("DEPRECATION")
fun Modifier.simple(padding: Int, border: Dp) = inspectable(
debugInspectorInfo {
name = "simple"
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupSecureFlagTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupSecureFlagTest.kt
index f4aec1d..44d7703 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupSecureFlagTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupSecureFlagTest.kt
@@ -114,6 +114,37 @@
assertThat(isSecureFlagEnabledForPopup()).isEqualTo(setSecureFlagOnActivity)
}
+ @Test
+ fun toggleFlagOnPopup_customFlagsOverload() {
+ var properties: PopupProperties by mutableStateOf(
+ PopupProperties(
+ flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+ inheritSecurePolicy = false,
+ )
+ )
+
+ rule.setContent {
+ TestPopup(properties)
+ }
+
+ assertThat(isSecureFlagEnabledForPopup()).isFalse()
+
+ // Toggle flag
+ properties = PopupProperties(
+ flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
+ WindowManager.LayoutParams.FLAG_SECURE,
+ inheritSecurePolicy = false,
+ )
+ assertThat(isSecureFlagEnabledForPopup()).isTrue()
+
+ // Set to inherit
+ properties = PopupProperties(
+ flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
+ inheritSecurePolicy = true,
+ )
+ assertThat(isSecureFlagEnabledForPopup()).isEqualTo(setSecureFlagOnActivity)
+ }
+
@Composable
fun TestPopup(popupProperties: PopupProperties) {
SimpleContainer {
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt
index c8cde80..cf421ef 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/window/PopupTest.kt
@@ -18,6 +18,7 @@
import android.view.View
import android.view.View.MEASURED_STATE_TOO_SMALL
import android.view.ViewGroup
+import android.view.WindowManager
import android.widget.FrameLayout
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
@@ -417,6 +418,37 @@
}
@Test
+ fun customFlags() {
+ val flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
+ WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
+ WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES or
+ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+
+ rule.setContent {
+ PopupTestTag(testTag) {
+ Popup(
+ properties = PopupProperties(
+ flags = flags,
+ inheritSecurePolicy = false,
+ )
+ ) {
+ Box(Modifier.size(50.dp))
+ }
+ }
+ }
+
+ // Make sure that current measurement/drawing is finished
+ rule.runOnIdle { }
+ val popupMatcher = PopupLayoutMatcher(testTag)
+ Espresso.onView(instanceOf(Owner::class.java))
+ .inRoot(popupMatcher)
+ .check(matches(isDisplayed()))
+ val capturedFlags = popupMatcher.lastSeenWindowParams!!.flags
+
+ assertThat(capturedFlags and flags).isEqualTo(flags)
+ }
+
+ @Test
fun didNotMeasureTooSmallLast() {
rule.setContent {
PopupTestTag(testTag) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 1b7aae9..cddaae2 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -1584,17 +1584,32 @@
)
}
- override fun dispatchGenericMotionEvent(event: MotionEvent) = when (event.actionMasked) {
- ACTION_SCROLL -> when {
- isBadMotionEvent(event) || !isAttachedToWindow ->
- super.dispatchGenericMotionEvent(event)
-
- event.isFromSource(SOURCE_ROTARY_ENCODER) -> handleRotaryEvent(event)
-
- else -> handleMotionEvent(event).dispatchedToAPointerInputModifier
+ override fun dispatchGenericMotionEvent(motionEvent: MotionEvent): Boolean {
+ if (hoverExitReceived) {
+ removeCallbacks(sendHoverExitEvent)
+ // Ignore ACTION_HOVER_EXIT if it is directly followed by an ACTION_SCROLL.
+ // Note: In some versions of Android Studio with screen mirroring, studio will
+ // incorrectly add an ACTION_HOVER_EXIT during a scroll event which causes
+ // issues (b/314269723), so we ignore the exit in that case.
+ if (motionEvent.actionMasked == ACTION_SCROLL) {
+ hoverExitReceived = false
+ } else {
+ sendHoverExitEvent.run()
+ }
}
- else -> super.dispatchGenericMotionEvent(event)
+ return when (motionEvent.actionMasked) {
+ ACTION_SCROLL -> when {
+ isBadMotionEvent(motionEvent) || !isAttachedToWindow ->
+ super.dispatchGenericMotionEvent(motionEvent)
+
+ motionEvent.isFromSource(SOURCE_ROTARY_ENCODER) -> handleRotaryEvent(motionEvent)
+
+ else -> handleMotionEvent(motionEvent).dispatchedToAPointerInputModifier
+ }
+
+ else -> super.dispatchGenericMotionEvent(motionEvent)
+ }
}
// TODO(shepshapard): Test this method.
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
index c2879c2..5c2c808 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
@@ -92,34 +92,32 @@
/**
* Properties used to customize the behavior of a [Popup].
*
- * @property focusable Whether the popup is focusable. When true, the popup will receive IME
- * events and key presses, such as when the back button is pressed.
+ * @property flags Behavioral flags of the popup, which will be passed to the popup window's
+ * [WindowManager.LayoutParams]. See [WindowManager.LayoutParams.flags] for customization options.
+ * If [inheritSecurePolicy] is true, the value of the [WindowManager.LayoutParams.FLAG_SECURE]
+ * bit will not be determined until the popup is constructed.
+ * @property inheritSecurePolicy Whether [WindowManager.LayoutParams.FLAG_SECURE] should be set
+ * according to [SecureFlagPolicy.Inherit]. Other [SecureFlagPolicy] behaviors should be set via
+ * [flags] directly.
* @property dismissOnBackPress Whether the popup can be dismissed by pressing the back button.
- * If true, pressing the back button will call onDismissRequest. Note that [focusable] must be
- * set to true in order to receive key events such as the back button - if the popup is not
- * focusable then this property does nothing.
+ * If true, pressing the back button will call onDismissRequest. Note that the popup must be
+ * [focusable] in order to receive key events such as the back button. If the popup is not
+ * [focusable], then this property does nothing.
* @property dismissOnClickOutside Whether the popup can be dismissed by clicking outside the
* popup's bounds. If true, clicking outside the popup will call onDismissRequest.
- * @property securePolicy Policy for setting [WindowManager.LayoutParams.FLAG_SECURE] on the popup's
- * window.
* @property excludeFromSystemGesture A flag to check whether to set the systemGestureExclusionRects.
* The default is true.
- * @property clippingEnabled Whether to allow the popup window to extend beyond the bounds of the
- * screen. By default the window is clipped to the screen boundaries. Setting this to false will
- * allow windows to be accurately positioned.
- * The default value is true.
* @property usePlatformDefaultWidth Whether the width of the popup's content should be limited to
* the platform default, which is smaller than the screen width.
*/
@Immutable
actual class PopupProperties constructor(
- actual val focusable: Boolean = false,
+ internal val flags: Int,
+ internal val inheritSecurePolicy: Boolean = true,
actual val dismissOnBackPress: Boolean = true,
actual val dismissOnClickOutside: Boolean = true,
- val securePolicy: SecureFlagPolicy = SecureFlagPolicy.Inherit,
val excludeFromSystemGesture: Boolean = true,
- actual val clippingEnabled: Boolean = true,
- val usePlatformDefaultWidth: Boolean = false
+ val usePlatformDefaultWidth: Boolean = false,
) {
actual constructor(
focusable: Boolean,
@@ -149,32 +147,93 @@
securePolicy = securePolicy,
excludeFromSystemGesture = excludeFromSystemGesture,
clippingEnabled = clippingEnabled,
- usePlatformDefaultWidth = false
+ usePlatformDefaultWidth = false,
)
+ /**
+ * Constructs a [PopupProperties] with the given behaviors. This constructor is to support
+ * multiplatform and maintain backwards compatibility. Consider the overload that takes a
+ * [flags] parameter if more precise control over the popup flags is desired.
+ *
+ * @param focusable Whether the popup is focusable. When true, the popup will receive IME
+ * events and key presses, such as when the back button is pressed.
+ * @param dismissOnBackPress Whether the popup can be dismissed by pressing the back button.
+ * If true, pressing the back button will call onDismissRequest. Note that [focusable] must be
+ * set to true in order to receive key events such as the back button. If the popup is not
+ * focusable, then this property does nothing.
+ * @param dismissOnClickOutside Whether the popup can be dismissed by clicking outside the
+ * popup's bounds. If true, clicking outside the popup will call onDismissRequest.
+ * @param securePolicy Policy for setting [WindowManager.LayoutParams.FLAG_SECURE] on the
+ * popup's window.
+ * @param excludeFromSystemGesture A flag to check whether to set the
+ * systemGestureExclusionRects. The default is true.
+ * @param clippingEnabled Whether to allow the popup window to extend beyond the bounds of the
+ * screen. By default the window is clipped to the screen boundaries. Setting this to false will
+ * allow windows to be accurately positioned. The default value is true.
+ * @param usePlatformDefaultWidth Whether the width of the popup's content should be limited to
+ * the platform default, which is smaller than the screen width.
+ */
+ constructor(
+ focusable: Boolean = false,
+ dismissOnBackPress: Boolean = true,
+ dismissOnClickOutside: Boolean = true,
+ securePolicy: SecureFlagPolicy = SecureFlagPolicy.Inherit,
+ excludeFromSystemGesture: Boolean = true,
+ clippingEnabled: Boolean = true,
+ usePlatformDefaultWidth: Boolean = false,
+ ) : this (
+ flags = createFlags(focusable, securePolicy, clippingEnabled),
+ inheritSecurePolicy = securePolicy == SecureFlagPolicy.Inherit,
+ dismissOnBackPress = dismissOnBackPress,
+ dismissOnClickOutside = dismissOnClickOutside,
+ excludeFromSystemGesture = excludeFromSystemGesture,
+ usePlatformDefaultWidth = usePlatformDefaultWidth,
+ )
+
+ /**
+ * Whether the popup is focusable. When true, the popup will receive IME events and key
+ * presses, such as when the back button is pressed.
+ */
+ actual val focusable: Boolean
+ get() = (flags and WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0
+
+ /**
+ * Policy for how [WindowManager.LayoutParams.FLAG_SECURE] is set on the popup's window.
+ */
+ val securePolicy: SecureFlagPolicy
+ get() = when {
+ inheritSecurePolicy -> SecureFlagPolicy.Inherit
+ (flags and WindowManager.LayoutParams.FLAG_SECURE) == 0 -> SecureFlagPolicy.SecureOff
+ else -> SecureFlagPolicy.SecureOn
+ }
+
+ /**
+ * Whether the popup window is clipped to the screen boundaries, or allowed to extend beyond
+ * the bounds of the screen.
+ */
+ actual val clippingEnabled: Boolean
+ get() = (flags and WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) == 0
+
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is PopupProperties) return false
- if (focusable != other.focusable) return false
+ if (flags != other.flags) return false
+ if (inheritSecurePolicy != other.inheritSecurePolicy) return false
if (dismissOnBackPress != other.dismissOnBackPress) return false
if (dismissOnClickOutside != other.dismissOnClickOutside) return false
- if (securePolicy != other.securePolicy) return false
if (excludeFromSystemGesture != other.excludeFromSystemGesture) return false
- if (clippingEnabled != other.clippingEnabled) return false
if (usePlatformDefaultWidth != other.usePlatformDefaultWidth) return false
return true
}
override fun hashCode(): Int {
- var result = dismissOnBackPress.hashCode()
- result = 31 * result + focusable.hashCode()
+ var result = flags
+ result = 31 * result + inheritSecurePolicy.hashCode()
result = 31 * result + dismissOnBackPress.hashCode()
result = 31 * result + dismissOnClickOutside.hashCode()
- result = 31 * result + securePolicy.hashCode()
result = 31 * result + excludeFromSystemGesture.hashCode()
- result = 31 * result + clippingEnabled.hashCode()
result = 31 * result + usePlatformDefaultWidth.hashCode()
return result
}
@@ -340,6 +399,27 @@
}
}
+private const val PopupPropertiesBaseFlags: Int =
+ WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+
+private fun createFlags(
+ focusable: Boolean,
+ securePolicy: SecureFlagPolicy,
+ clippingEnabled: Boolean,
+): Int {
+ var flags = PopupPropertiesBaseFlags
+ if (!focusable) {
+ flags = flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ }
+ if (securePolicy == SecureFlagPolicy.SecureOn) {
+ flags = flags or WindowManager.LayoutParams.FLAG_SECURE
+ }
+ if (!clippingEnabled) {
+ flags = flags or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+ }
+ return flags
+}
+
// TODO(b/139861182): This is a hack to work around Popups not using Semantics for test tags
// We should either remove it, or come up with an abstracted general solution that isn't specific
// to Popup
@@ -585,61 +665,31 @@
backCallback = null
}
- /**
- * Set whether the popup can grab a focus and support dismissal.
- */
- private fun setIsFocusable(isFocusable: Boolean) = applyNewFlags(
- if (!isFocusable) {
- params.flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- } else {
- params.flags and (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE.inv())
- }
- )
-
- private fun setSecurePolicy(securePolicy: SecureFlagPolicy) {
- val secureFlagEnabled =
- securePolicy.shouldApplySecureFlag(composeView.isFlagSecureEnabled())
- applyNewFlags(
- if (secureFlagEnabled) {
- params.flags or WindowManager.LayoutParams.FLAG_SECURE
- } else {
- params.flags and (WindowManager.LayoutParams.FLAG_SECURE.inv())
- }
- )
- }
-
- private fun setClippingEnabled(clippingEnabled: Boolean) = applyNewFlags(
- if (clippingEnabled) {
- params.flags and (WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS.inv())
- } else {
- params.flags or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
- }
- )
-
fun updateParameters(
onDismissRequest: (() -> Unit)?,
properties: PopupProperties,
testTag: String,
- layoutDirection: LayoutDirection
+ layoutDirection: LayoutDirection,
) {
this.onDismissRequest = onDismissRequest
+ this.testTag = testTag
+ updatePopupProperties(properties)
+ superSetLayoutDirection(layoutDirection)
+ }
+
+ private fun updatePopupProperties(properties: PopupProperties) {
+ if (this.properties == properties) return
+
if (properties.usePlatformDefaultWidth && !this.properties.usePlatformDefaultWidth) {
// Undo fixed size in internalOnLayout, which would suppress size changes when
// usePlatformDefaultWidth is true.
params.width = WindowManager.LayoutParams.WRAP_CONTENT
params.height = WindowManager.LayoutParams.WRAP_CONTENT
- popupLayoutHelper.updateViewLayout(windowManager, this, params)
}
- this.properties = properties
- this.testTag = testTag
- setIsFocusable(properties.focusable)
- setSecurePolicy(properties.securePolicy)
- setClippingEnabled(properties.clippingEnabled)
- superSetLayoutDirection(layoutDirection)
- }
- private fun applyNewFlags(flags: Int) {
- params.flags = flags
+ this.properties = properties
+ params.flags = properties.flagsWithSecureFlagInherited(composeView.isFlagSecureEnabled())
+
popupLayoutHelper.updateViewLayout(windowManager, this, params)
}
@@ -789,17 +839,7 @@
// Start to position the popup in the top left corner, a new position will be calculated
gravity = Gravity.START or Gravity.TOP
- // Flags specific to android.widget.PopupWindow
- flags = flags and (
- WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES or
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
- WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
- WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM or
- WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- ).inv()
-
- // Enables us to intercept outside clicks even when popup is not focusable
- flags = flags or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ flags = properties.flagsWithSecureFlagInherited(composeView.isFlagSecureEnabled())
type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL
@@ -909,6 +949,14 @@
return false
}
+private fun PopupProperties.flagsWithSecureFlagInherited(
+ isParentFlagSecureEnabled: Boolean,
+): Int = if (this.inheritSecurePolicy && isParentFlagSecureEnabled) {
+ this.flags or WindowManager.LayoutParams.FLAG_SECURE
+} else {
+ this.flags
+}
+
private fun Rect.toIntBounds() = IntRect(
left = left,
top = top,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Expect.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Expect.kt
index e4b50a2..46900a3 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Expect.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Expect.kt
@@ -21,6 +21,8 @@
internal expect fun areObjectsOfSameType(a: Any, b: Any): Boolean
+internal expect fun classKeyForObject(a: Any): Any
+
/**
* Reflectively resolves the properties and name of [element], and populates it in the receiver.
* This function is used by [ModifierNodeElement] as a default implementation to provide inspection
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt
index b00cd91..60fc8a6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt
@@ -16,8 +16,10 @@
package androidx.compose.ui.node
+import androidx.collection.mutableObjectIntMapOf
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.classKeyForObject
import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.focus.FocusEventModifierNode
import androidx.compose.ui.focus.FocusProperties
@@ -152,65 +154,68 @@
return mask
}
+private val classToKindSetMap = mutableObjectIntMapOf<Any>()
@OptIn(ExperimentalComposeUiApi::class)
internal fun calculateNodeKindSetFrom(node: Modifier.Node): Int {
// This function does not take delegates into account, as a result, the kindSet will never
// change, so if it is non-zero, it means we've already calculated it and we can just bail
// early here.
if (node.kindSet != 0) return node.kindSet
- var mask = Nodes.Any.mask
- if (node is LayoutModifierNode) {
- mask = mask or Nodes.Layout
+ return classToKindSetMap.getOrPut(classKeyForObject(node)) {
+ var mask = Nodes.Any.mask
+ if (node is LayoutModifierNode) {
+ mask = mask or Nodes.Layout
+ }
+ if (node is DrawModifierNode) {
+ mask = mask or Nodes.Draw
+ }
+ if (node is SemanticsModifierNode) {
+ mask = mask or Nodes.Semantics
+ }
+ if (node is PointerInputModifierNode) {
+ mask = mask or Nodes.PointerInput
+ }
+ if (node is ModifierLocalModifierNode) {
+ mask = mask or Nodes.Locals
+ }
+ if (node is ParentDataModifierNode) {
+ mask = mask or Nodes.ParentData
+ }
+ if (node is LayoutAwareModifierNode) {
+ mask = mask or Nodes.LayoutAware
+ }
+ if (node is GlobalPositionAwareModifierNode) {
+ mask = mask or Nodes.GlobalPositionAware
+ }
+ if (node is ApproachLayoutModifierNode) {
+ mask = mask or Nodes.IntermediateMeasure
+ }
+ if (node is FocusTargetNode) {
+ mask = mask or Nodes.FocusTarget
+ }
+ if (node is FocusPropertiesModifierNode) {
+ mask = mask or Nodes.FocusProperties
+ }
+ if (node is FocusEventModifierNode) {
+ mask = mask or Nodes.FocusEvent
+ }
+ if (node is KeyInputModifierNode) {
+ mask = mask or Nodes.KeyInput
+ }
+ if (node is RotaryInputModifierNode) {
+ mask = mask or Nodes.RotaryInput
+ }
+ if (node is CompositionLocalConsumerModifierNode) {
+ mask = mask or Nodes.CompositionLocalConsumer
+ }
+ if (node is SoftKeyboardInterceptionModifierNode) {
+ mask = mask or Nodes.SoftKeyboardKeyInput
+ }
+ if (node is TraversableNode) {
+ mask = mask or Nodes.Traversable
+ }
+ mask
}
- if (node is DrawModifierNode) {
- mask = mask or Nodes.Draw
- }
- if (node is SemanticsModifierNode) {
- mask = mask or Nodes.Semantics
- }
- if (node is PointerInputModifierNode) {
- mask = mask or Nodes.PointerInput
- }
- if (node is ModifierLocalModifierNode) {
- mask = mask or Nodes.Locals
- }
- if (node is ParentDataModifierNode) {
- mask = mask or Nodes.ParentData
- }
- if (node is LayoutAwareModifierNode) {
- mask = mask or Nodes.LayoutAware
- }
- if (node is GlobalPositionAwareModifierNode) {
- mask = mask or Nodes.GlobalPositionAware
- }
- if (node is ApproachLayoutModifierNode) {
- mask = mask or Nodes.IntermediateMeasure
- }
- if (node is FocusTargetNode) {
- mask = mask or Nodes.FocusTarget
- }
- if (node is FocusPropertiesModifierNode) {
- mask = mask or Nodes.FocusProperties
- }
- if (node is FocusEventModifierNode) {
- mask = mask or Nodes.FocusEvent
- }
- if (node is KeyInputModifierNode) {
- mask = mask or Nodes.KeyInput
- }
- if (node is RotaryInputModifierNode) {
- mask = mask or Nodes.RotaryInput
- }
- if (node is CompositionLocalConsumerModifierNode) {
- mask = mask or Nodes.CompositionLocalConsumer
- }
- if (node is SoftKeyboardInterceptionModifierNode) {
- mask = mask or Nodes.SoftKeyboardKeyInput
- }
- if (node is TraversableNode) {
- mask = mask or Nodes.Traversable
- }
- return mask
}
@Suppress("ConstPropertyName")
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InspectableValue.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InspectableValue.kt
index 02bedf9..970de2b 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InspectableValue.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InspectableValue.kt
@@ -140,6 +140,14 @@
*
* @sample androidx.compose.ui.samples.InspectableModifierSample
*/
+@Suppress("DeprecatedCallableAddReplaceWith")
+@Deprecated(
+ "This API will create more invalidations of your modifier than necessary, so it's " +
+ "use is discouraged. Implementing the inspectableProperties method on " +
+ "ModifierNodeElement is the recommended zero-cost alternative to exposing properties " +
+ "on a Modifier to tooling.",
+ level = DeprecationLevel.WARNING,
+)
inline fun Modifier.inspectable(
noinline inspectorInfo: InspectorInfo.() -> Unit,
factory: Modifier.() -> Modifier
diff --git a/compose/ui/ui/src/jvmMain/kotlin/androidx/compose/ui/Actual.jvm.kt b/compose/ui/ui/src/jvmMain/kotlin/androidx/compose/ui/Actual.jvm.kt
index 84f9030..f85672e 100644
--- a/compose/ui/ui/src/jvmMain/kotlin/androidx/compose/ui/Actual.jvm.kt
+++ b/compose/ui/ui/src/jvmMain/kotlin/androidx/compose/ui/Actual.jvm.kt
@@ -24,6 +24,10 @@
return a::class.java === b::class.java
}
+internal actual fun classKeyForObject(a: Any): Any {
+ return a.javaClass
+}
+
// TODO: For non-JVM platforms, you can revive the kotlin-reflect implementation from
// https://android-review.googlesource.com/c/platform/frameworks/support/+/2441379
internal actual fun InspectorInfo.tryPopulateReflectively(
diff --git a/core/core/lint-baseline.xml b/core/core/lint-baseline.xml
index 2df4e9c..5544e25 100644
--- a/core/core/lint-baseline.xml
+++ b/core/core/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="NewApi"
@@ -579,15 +579,6 @@
<issue
id="NewApi"
- message="Class requires API level 26 (current min is 19): `OreoCallback`"
- errorLine1=" if (callback instanceof OreoCallback && Build.VERSION.SDK_INT >= 26) {"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/core/widget/TextViewCompat.java"/>
- </issue>
-
- <issue
- id="NewApi"
message="Call requires API level 20 (current min is 19): `android.view.View#requestApplyInsets`"
errorLine1=" post { requestApplyInsets() }"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index 6294b28..0c69500 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -405,17 +405,18 @@
WARN: .*\/unzippedJvmSources\/androidx\/webkit\/WebViewCompat\.java:[0-9]+ Missing @param tag for parameter `webview` in DFunction removeWebMessageListener
WARN: .*\/unzippedJvmSources\/androidx\/work\/testing\/TestListenableWorkerBuilder\.kt:UnknownLine Missing @param tag for parameter `tags` in DFunction TestListenableWorkerBuilder
WARN: .*\/unzippedJvmSources\/androidx\/work\/testing\/TestWorkerBuilder\.kt:UnknownLine Missing @param tag for parameter `tags` in DFunction TestWorkerBuilder
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `placeholdersEnabled` in DFunction LoadInitialParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedInitialKey` in DFunction LoadInitialParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadInitialParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `key` in DFunction LoadParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadParams
-WARN: .*\/unzipped.*\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `nextPageKey` in DFunction onResult
-WARN: .*\/unzipped.*\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `previousPageKey` in DFunction onResult
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `placeholdersEnabled` in DFunction LoadInitialParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadInitialParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `key` in DFunction LoadParams
-WARN: .*\/unzippedJvmSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `placeholdersEnabled` in DFunction LoadInitialParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedInitialKey` in DFunction LoadInitialParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadInitialParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `key` in DFunction LoadParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/ItemKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `nextPageKey` in DFunction onResult
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `previousPageKey` in DFunction onResult
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `placeholdersEnabled` in DFunction LoadInitialParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadInitialParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `key` in DFunction LoadParams
+WARN: .*\/unzippedMultiplatformSources\/commonJvmAndroidMain\/androidx\/paging\/PageKeyedDataSource\.jvm\.kt:[0-9]+ Missing @param tag for parameter `requestedLoadSize` in DFunction LoadParams
+WARN: .*\/unzippedMultiplatformSources\/commonMain\/androidx\/paging\/LoadState\.kt:[0-9]+ Failed to resolve See androidx\.paging\.PagedList\.retry in DClass Error\. Did you mean androidx\.paging\.PagedList#retry\?
WARN: .*\/unzippedMultiplatformSources\/androidMain\/androidx\/compose\/animation\/graphics\/res\/AnimatedVectorPainterResources\.android\.kt:[0-9]+ Missing @param tag for parameter `animatedImageVector` in DFunction rememberAnimatedVectorPainter
WARN: .*\/unzippedMultiplatformSources\/androidMain\/androidx\/compose\/material\/AndroidMenu\.android\.kt:[0-9]+ Missing @param tag for parameter `content` in DFunction DropdownMenuItem
WARN: .*\/unzippedMultiplatformSources\/androidMain\/androidx\/compose\/ui\/graphics\/AndroidPath\.android\.kt:[0-9]+ Missing @param tag for parameter `operation` in DFunction op
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index e5a79a8..d61a894 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -201,7 +201,7 @@
docs("androidx.graphics:graphics-core:1.0.0-beta01")
samples("androidx.graphics:graphics-core-samples:1.0.0-beta01")
docs("androidx.graphics:graphics-path:1.0.0-beta02")
- docs("androidx.graphics:graphics-shapes:1.0.0-alpha05")
+ kmpDocs("androidx.graphics:graphics-shapes:1.0.0-alpha05")
docs("androidx.gridlayout:gridlayout:1.1.0-beta01")
docs("androidx.health.connect:connect-client:1.1.0-alpha07")
samples("androidx.health.connect:connect-client-samples:1.1.0-alpha07")
@@ -292,7 +292,7 @@
docs("androidx.navigation:navigation-testing:2.8.0-alpha02")
docs("androidx.navigation:navigation-ui:2.8.0-alpha02")
docs("androidx.navigation:navigation-ui-ktx:2.8.0-alpha02")
- docs("androidx.paging:paging-common:3.3.0-alpha03")
+ kmpDocs("androidx.paging:paging-common:3.3.0-alpha03")
docs("androidx.paging:paging-common-ktx:3.3.0-alpha03")
kmpDocs("androidx.paging:paging-compose:3.3.0-alpha03")
samples("androidx.paging:paging-compose-samples:3.3.0-alpha03")
@@ -303,7 +303,7 @@
docs("androidx.paging:paging-rxjava2-ktx:3.3.0-alpha03")
docs("androidx.paging:paging-rxjava3:3.3.0-alpha03")
samples("androidx.paging:paging-samples:3.3.0-alpha03")
- docs("androidx.paging:paging-testing:3.3.0-alpha03")
+ kmpDocs("androidx.paging:paging-testing:3.3.0-alpha03")
docs("androidx.palette:palette:1.0.0")
docs("androidx.palette:palette-ktx:1.0.0")
docs("androidx.percentlayout:percentlayout:1.0.1")
@@ -358,7 +358,7 @@
docs("androidx.sqlite:sqlite-ktx:2.4.0")
docs("androidx.startup:startup-runtime:1.2.0-alpha02")
docs("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
- // androidx.test is not hosted in androidx\
+ // androidx.test is not hosted in androidx
docsWithoutApiSince("androidx.test:core:1.6.0-alpha05")
docsWithoutApiSince("androidx.test:core-ktx:1.6.0-alpha05")
docsWithoutApiSince("androidx.test:monitor:1.7.0-alpha04")
@@ -452,7 +452,7 @@
docs("androidx.window.extensions.core:core:1.0.0")
docs("androidx.window:window:1.3.0-alpha02")
stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
- docs("androidx.window:window-core:1.3.0-alpha02")
+ kmpDocs("androidx.window:window-core:1.3.0-alpha02")
stubs("androidx.window:window-extensions:1.0.0-alpha01")
docs("androidx.window:window-java:1.3.0-alpha02")
docs("androidx.window:window-rxjava2:1.3.0-alpha02")
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index d4907e5..a630cd4 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -82,9 +82,11 @@
kmpDocs(project(":compose:foundation:foundation-layout"))
samples(project(":compose:foundation:foundation-layout:foundation-layout-samples"))
samples(project(":compose:foundation:foundation:foundation-samples"))
+ kmpDocs(project(":compose:material3:adaptive:adaptive"))
+ kmpDocs(project(":compose:material3:adaptive:adaptive-layout"))
+ kmpDocs(project(":compose:material3:adaptive:adaptive-navigation"))
+ samples(project(":compose:material3:adaptive:adaptive-samples"))
kmpDocs(project(":compose:material3:material3"))
- kmpDocs(project(":compose:material3:material3-adaptive"))
- samples(project(":compose:material3:material3-adaptive:material3-adaptive-samples"))
kmpDocs(project(":compose:material3:material3-adaptive-navigation-suite"))
samples(project(":compose:material3:material3-adaptive-navigation-suite:material3-adaptive-navigation-suite-samples"))
kmpDocs(project(":compose:material3:material3-common"))
diff --git a/external/paparazzi/paparazzi-agent/build.gradle b/external/paparazzi/paparazzi-agent/build.gradle
deleted file mode 100644
index 802d417..0000000
--- a/external/paparazzi/paparazzi-agent/build.gradle
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * This file was created using the `create_project.py` script located in the
- * `<AndroidX root>/development/project-creator` directory.
- *
- * Please use that script when creating a new project, rather than copying an existing project and
- * modifying its settings.
- */
-import androidx.build.LibraryType
-
-plugins {
- id("AndroidXPlugin")
- id("kotlin")
-}
-
-dependencies {
- api(libs.kotlinStdlib)
- api(libs.junit)
- implementation(libs.byteBuddy)
- implementation(libs.byteBuddyAgent)
- testImplementation(libs.assertj)
-}
-
-androidx {
- name = "Paparazzi Agent - AndroidX Fork"
- type = LibraryType.INTERNAL_HOST_TEST_LIBRARY
-}
diff --git a/external/paparazzi/paparazzi-agent/src/main/java/app/cash/paparazzi/agent/AgentTestRule.kt b/external/paparazzi/paparazzi-agent/src/main/java/app/cash/paparazzi/agent/AgentTestRule.kt
deleted file mode 100644
index b79b5d5..0000000
--- a/external/paparazzi/paparazzi-agent/src/main/java/app/cash/paparazzi/agent/AgentTestRule.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package app.cash.paparazzi.agent
-
-import net.bytebuddy.agent.ByteBuddyAgent
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-
-class AgentTestRule : TestRule {
- override fun apply(
- base: Statement,
- description: Description
- ) = object : Statement() {
- override fun evaluate() {
- ByteBuddyAgent.install()
- InterceptorRegistrar.registerMethodInterceptors()
- // interceptors are statically retained until test process finishes, so no need to cleanup
- base.evaluate()
- }
- }
-}
diff --git a/external/paparazzi/paparazzi-agent/src/main/java/app/cash/paparazzi/agent/InterceptorRegistrar.kt b/external/paparazzi/paparazzi-agent/src/main/java/app/cash/paparazzi/agent/InterceptorRegistrar.kt
deleted file mode 100644
index b436835..0000000
--- a/external/paparazzi/paparazzi-agent/src/main/java/app/cash/paparazzi/agent/InterceptorRegistrar.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package app.cash.paparazzi.agent
-
-import net.bytebuddy.ByteBuddy
-import net.bytebuddy.dynamic.loading.ClassReloadingStrategy
-import net.bytebuddy.implementation.MethodDelegation
-import net.bytebuddy.matcher.ElementMatchers
-
-object InterceptorRegistrar {
- private val byteBuddy = ByteBuddy()
- private val methodInterceptors = mutableListOf<() -> Unit>()
-
- fun addMethodInterceptor(
- receiver: Class<*>,
- methodName: String,
- interceptor: Class<*>
- ) = addMethodInterceptors(receiver, setOf(methodName to interceptor))
-
- fun addMethodInterceptors(
- receiver: Class<*>,
- methodNamesToInterceptors: Set<Pair<String, Class<*>>>
- ) {
- methodInterceptors += {
- var builder = byteBuddy
- .redefine(receiver)
-
- methodNamesToInterceptors.forEach {
- builder = builder
- .method(ElementMatchers.named(it.first))
- .intercept(MethodDelegation.to(it.second))
- }
-
- builder
- .make()
- .load(receiver.classLoader, ClassReloadingStrategy.fromInstalledAgent())
- }
- }
-
- fun registerMethodInterceptors() {
- methodInterceptors.forEach { it.invoke() }
- }
-
- fun clearMethodInterceptors() {
- methodInterceptors.clear()
- }
-}
diff --git a/external/paparazzi/paparazzi-agent/src/test/java/app/cash/paparazzi/agent/InterceptorRegistrarTest.kt b/external/paparazzi/paparazzi-agent/src/test/java/app/cash/paparazzi/agent/InterceptorRegistrarTest.kt
deleted file mode 100644
index 1113073..0000000
--- a/external/paparazzi/paparazzi-agent/src/test/java/app/cash/paparazzi/agent/InterceptorRegistrarTest.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package app.cash.paparazzi.agent
-
-import net.bytebuddy.agent.ByteBuddyAgent
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-
-class InterceptorRegistrarTest {
- @Before
- fun setup() {
- InterceptorRegistrar.addMethodInterceptors(
- Utils::class.java,
- setOf(
- "log1" to Interceptor1::class.java,
- "log2" to Interceptor2::class.java
- )
- )
-
- ByteBuddyAgent.install()
- InterceptorRegistrar.registerMethodInterceptors()
- }
-
- @Test
- fun test() {
- Utils.log1()
- Utils.log2()
-
- assertThat(logs).containsExactly("intercept1", "intercept2")
- }
-
- @After
- fun teardown() {
- InterceptorRegistrar.clearMethodInterceptors()
- }
-
- object Utils {
- fun log1() {
- logs += "original1"
- }
-
- fun log2() {
- logs += "original2"
- }
- }
-
- object Interceptor1 {
- @Suppress("unused")
- @JvmStatic
- fun intercept() {
- logs += "intercept1"
- }
- }
-
- object Interceptor2 {
- @Suppress("unused")
- @JvmStatic
- fun intercept() {
- logs += "intercept2"
- }
- }
-
- companion object {
- private val logs = mutableListOf<String>()
- }
-}
diff --git a/external/paparazzi/paparazzi/build.gradle b/external/paparazzi/paparazzi/build.gradle
deleted file mode 100644
index bc018ac..0000000
--- a/external/paparazzi/paparazzi/build.gradle
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * This file was created using the `create_project.py` script located in the
- * `<AndroidX root>/development/project-creator` directory.
- *
- * Please use that script when creating a new project, rather than copying an existing project and
- * modifying its settings.
- */
-import androidx.build.LibraryType
-import org.gradle.api.artifacts.transform.TransformParameters.None
-import java.util.zip.ZipInputStream
-
-plugins {
- id("AndroidXPlugin")
- id("kotlin")
- id("com.google.devtools.ksp")
- id("AndroidXComposePlugin")
-}
-
-androidx.configureAarAsJarForConfiguration("compileOnly")
-androidx.configureAarAsJarForConfiguration("testImplementation")
-
-dependencies {
- api("androidx.annotation:annotation:1.3.0")
- api("com.android.tools.layoutlib:layoutlib-api:27.2.2")
- api("com.android.tools:common:27.1.2")
- api(libs.androidToolsNinepatch)
- api("com.android.tools:sdk-common:26.6.4")
- api(libs.guava)
- api(libs.junit)
- api(libs.kotlinStdlib)
- api(libs.kotlinCoroutinesCore)
- api(libs.kxml2)
- api(libs.okio)
- api(libs.paparazziNativeJvm)
- constraints {
- implementation(libs.kotlinReflect) {
- because("sdk-common depends on an old kotlin-reflect")
- }
- }
-
- implementation(project(":external:paparazzi:paparazzi-agent"))
- implementation(libs.jcodec)
- implementation(libs.jcodecJavaSe)
- implementation(libs.moshi)
- implementation(libs.moshiAdapters)
-
- compileOnlyAarAsJar("androidx.compose.runtime:runtime:1.2.1")
- compileOnlyAarAsJar("androidx.compose.ui:ui:1.2.1")
- compileOnly(project(":lifecycle:lifecycle-common"))
- compileOnlyAarAsJar(project(":lifecycle:lifecycle-runtime"))
- compileOnlyAarAsJar("androidx.savedstate:savedstate:1.2.0")
-
- ksp(libs.moshiCodeGen)
-
- testImplementation(libs.assertj)
- testImplementationAarAsJar("androidx.compose.runtime:runtime:1.2.1")
-}
-
-androidx {
- name = "Paparazzi - AndroidX Fork"
- type = LibraryType.INTERNAL_HOST_TEST_LIBRARY
-}
\ No newline at end of file
diff --git a/external/paparazzi/paparazzi/lint-baseline.xml b/external/paparazzi/paparazzi/lint-baseline.xml
deleted file mode 100644
index a53cf10..0000000
--- a/external/paparazzi/paparazzi/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(100)"
- errorLine2=" ~~~~~">
- <location
- file="src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt"/>
- </issue>
-
-</issues>
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt
deleted file mode 100644
index 7345548..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package app.cash.paparazzi
-
-import com.android.ide.common.rendering.api.HardwareConfig
-import com.android.ide.common.resources.configuration.CountryCodeQualifier
-import com.android.ide.common.resources.configuration.DensityQualifier
-import com.android.ide.common.resources.configuration.FolderConfiguration
-import com.android.ide.common.resources.configuration.KeyboardStateQualifier
-import com.android.ide.common.resources.configuration.LayoutDirectionQualifier
-import com.android.ide.common.resources.configuration.LocaleQualifier
-import com.android.ide.common.resources.configuration.NavigationMethodQualifier
-import com.android.ide.common.resources.configuration.NetworkCodeQualifier
-import com.android.ide.common.resources.configuration.NightModeQualifier
-import com.android.ide.common.resources.configuration.ScreenDimensionQualifier
-import com.android.ide.common.resources.configuration.ScreenOrientationQualifier
-import com.android.ide.common.resources.configuration.ScreenRatioQualifier
-import com.android.ide.common.resources.configuration.ScreenSizeQualifier
-import com.android.ide.common.resources.configuration.TextInputMethodQualifier
-import com.android.ide.common.resources.configuration.TouchScreenQualifier
-import com.android.ide.common.resources.configuration.UiModeQualifier
-import com.android.ide.common.resources.configuration.VersionQualifier
-import com.android.resources.Density
-import com.android.resources.Keyboard
-import com.android.resources.KeyboardState
-import com.android.resources.LayoutDirection
-import com.android.resources.Navigation
-import com.android.resources.NightMode
-import com.android.resources.NightMode.NOTNIGHT
-import com.android.resources.ScreenOrientation
-import com.android.resources.ScreenRatio
-import com.android.resources.ScreenSize
-import com.android.resources.TouchScreen
-import com.android.resources.UiMode
-import com.google.android.collect.Maps
-import java.io.File
-import java.io.FileInputStream
-import java.io.IOException
-import java.util.Properties
-import org.xmlpull.v1.XmlPullParser
-import org.xmlpull.v1.XmlPullParserException
-import org.xmlpull.v1.XmlPullParserFactory
-
-/**
- * Provides [FolderConfiguration] and [HardwareConfig] for various devices. Also provides utility
- * methods to parse `build.prop` and `attrs.xml` to generate the appropriate maps.
- *
- * Defaults are for a Nexus 4 device.
- */
-data class DeviceConfig(
- val screenHeight: Int = 1280,
- val screenWidth: Int = 768,
- val xdpi: Int = 320,
- val ydpi: Int = 320,
- val orientation: ScreenOrientation = ScreenOrientation.PORTRAIT,
- val nightMode: NightMode = NOTNIGHT,
- val density: Density = Density.XHIGH,
- val fontScale: Float = 1f,
- val layoutDirection: LayoutDirection = LayoutDirection.LTR,
- val locale: String = "en",
- val ratio: ScreenRatio = ScreenRatio.NOTLONG,
- val size: ScreenSize = ScreenSize.NORMAL,
- val keyboard: Keyboard = Keyboard.NOKEY,
- val touchScreen: TouchScreen = TouchScreen.FINGER,
- val keyboardState: KeyboardState = KeyboardState.SOFT,
- val softButtons: Boolean = true,
- val navigation: Navigation = Navigation.NONAV,
- val released: String = "November 13, 2012"
-) {
- val folderConfiguration: FolderConfiguration
- get() = FolderConfiguration.createDefault()
- .apply {
- densityQualifier = DensityQualifier(density)
- navigationMethodQualifier = NavigationMethodQualifier(navigation)
- screenDimensionQualifier = when {
- screenWidth > screenHeight -> ScreenDimensionQualifier(screenWidth, screenHeight)
- else -> ScreenDimensionQualifier(screenHeight, screenWidth)
- }
- screenRatioQualifier = ScreenRatioQualifier(ratio)
- screenSizeQualifier = ScreenSizeQualifier(size)
- textInputMethodQualifier = TextInputMethodQualifier(keyboard)
- touchTypeQualifier = TouchScreenQualifier(touchScreen)
- keyboardStateQualifier = KeyboardStateQualifier(keyboardState)
- screenOrientationQualifier = ScreenOrientationQualifier(orientation)
-
- updateScreenWidthAndHeight()
- uiModeQualifier = UiModeQualifier(UiMode.NORMAL)
- nightModeQualifier = NightModeQualifier(nightMode)
- countryCodeQualifier = CountryCodeQualifier()
- layoutDirectionQualifier = LayoutDirectionQualifier(layoutDirection)
- networkCodeQualifier = NetworkCodeQualifier()
- localeQualifier = LocaleQualifier.getQualifier(locale)
- versionQualifier = VersionQualifier()
- }
-
- val hardwareConfig: HardwareConfig
- get() = HardwareConfig(
- screenWidth, screenHeight, density, xdpi.toFloat(), ydpi.toFloat(), size,
- orientation, null, softButtons
- )
-
- /**
- * Device specs per:
- * https://android.googlesource.com/platform/tools/base/+/mirror-goog-studio-master-dev/sdklib/src/main/java/com/android/sdklib/devices/nexus.xml
- *
- * Release dates obtained from Wikipedia.
- */
-
- companion object {
- @JvmField
- val NEXUS_4 = DeviceConfig()
-
- @JvmField
- val NEXUS_5 = DeviceConfig(
- screenHeight = 1920,
- screenWidth = 1080,
- xdpi = 445,
- ydpi = 445,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.XXHIGH,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 31, 2013"
- )
-
- @JvmField
- val NEXUS_7 = DeviceConfig(
- screenHeight = 1920,
- screenWidth = 1200,
- xdpi = 323,
- ydpi = 323,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.XHIGH,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.LARGE,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "July 26, 2013"
- )
-
- @JvmField
- val NEXUS_10 = DeviceConfig(
- screenHeight = 1600,
- screenWidth = 2560,
- xdpi = 300,
- ydpi = 300,
- orientation = ScreenOrientation.LANDSCAPE,
- density = Density.XHIGH,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.XLARGE,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "November 13, 2012"
- )
-
- @JvmField
- val NEXUS_5_LAND = DeviceConfig(
- screenHeight = 1080,
- screenWidth = 1920,
- xdpi = 445,
- ydpi = 445,
- orientation = ScreenOrientation.LANDSCAPE,
- density = Density.XXHIGH,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 31, 2013"
- )
-
- @JvmField
- val NEXUS_7_2012 = DeviceConfig(
- screenHeight = 1280,
- screenWidth = 800,
- xdpi = 195,
- ydpi = 200,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.TV,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.LARGE,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "July 13, 2012"
- )
-
- @JvmField
- val PIXEL_C = DeviceConfig(
- screenHeight = 1800,
- screenWidth = 2560,
- xdpi = 308,
- ydpi = 308,
- orientation = ScreenOrientation.LANDSCAPE,
- density = Density.XHIGH,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.XLARGE,
- keyboard = Keyboard.QWERTY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "December 8, 2015"
- )
-
- @JvmField
- val PIXEL = DeviceConfig(
- screenHeight = 1920,
- screenWidth = 1080,
- xdpi = 440,
- ydpi = 440,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_420,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 20, 2016"
- )
-
- @JvmField
- val PIXEL_XL = DeviceConfig(
- screenHeight = 2560,
- screenWidth = 1440,
- xdpi = 534,
- ydpi = 534,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_560,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 20, 2016"
- )
-
- @JvmField
- val PIXEL_2 = DeviceConfig(
- screenHeight = 1920,
- screenWidth = 1080,
- xdpi = 442,
- ydpi = 443,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_420,
- ratio = ScreenRatio.NOTLONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 19, 2017"
- )
-
- @JvmField
- val PIXEL_2_XL = DeviceConfig(
- screenHeight = 2880,
- screenWidth = 1440,
- xdpi = 537,
- ydpi = 537,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_560,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 19, 2017"
- )
-
- @JvmField
- val PIXEL_3 = DeviceConfig(
- screenHeight = 2160,
- screenWidth = 1080,
- xdpi = 442,
- ydpi = 442,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_440,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 18, 2018"
- )
-
- @JvmField
- val PIXEL_3_XL = DeviceConfig(
- screenHeight = 2960,
- screenWidth = 1440,
- xdpi = 522,
- ydpi = 522,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_560,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 18, 2018"
- )
-
- @JvmField
- val PIXEL_3A = DeviceConfig(
- screenHeight = 2220,
- screenWidth = 1080,
- xdpi = 442,
- ydpi = 444,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_440,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "May 7, 2019"
- )
-
- @JvmField
- val PIXEL_3A_XL = DeviceConfig(
- screenHeight = 2160,
- screenWidth = 1080,
- xdpi = 397,
- ydpi = 400,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_400,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "May 7, 2019"
- )
-
- @JvmField
- val PIXEL_4 = DeviceConfig(
- screenHeight = 2280,
- screenWidth = 1080,
- xdpi = 444,
- ydpi = 444,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_440,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 24, 2019"
- )
-
- @JvmField
- val PIXEL_4_XL = DeviceConfig(
- screenHeight = 3040,
- screenWidth = 1440,
- xdpi = 537,
- ydpi = 537,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_560,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 24, 2019"
- )
-
- @JvmField
- val PIXEL_4A = DeviceConfig(
- screenHeight = 2340,
- screenWidth = 1080,
- xdpi = 442,
- ydpi = 444,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_440,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "August 20, 2020"
- )
-
- @JvmField
- val PIXEL_5 = DeviceConfig(
- screenHeight = 2340,
- screenWidth = 1080,
- xdpi = 442,
- ydpi = 444,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_440,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 15, 2020"
- )
-
- @JvmField
- val PIXEL_6 = DeviceConfig(
- screenHeight = 2400,
- screenWidth = 1080,
- xdpi = 406,
- ydpi = 411,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_420,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 28, 2021"
- )
-
- @JvmField
- val PIXEL_6_PRO = DeviceConfig(
- screenHeight = 3120,
- screenWidth = 1440,
- xdpi = 512,
- ydpi = 512,
- orientation = ScreenOrientation.PORTRAIT,
- density = Density.DPI_560,
- ratio = ScreenRatio.LONG,
- size = ScreenSize.NORMAL,
- keyboard = Keyboard.NOKEY,
- touchScreen = TouchScreen.FINGER,
- keyboardState = KeyboardState.SOFT,
- softButtons = true,
- navigation = Navigation.NONAV,
- released = "October 28, 2021"
- )
-
- private const val TAG_ATTR = "attr"
- private const val TAG_ENUM = "enum"
- private const val TAG_FLAG = "flag"
- private const val ATTR_NAME = "name"
- private const val ATTR_VALUE = "value"
-
- @Throws(IOException::class)
- fun loadProperties(path: File): Map<String, String> {
- val p = Properties()
- val map = Maps.newHashMap<String, String>()
- p.load(FileInputStream(path))
- for (key in p.stringPropertyNames()) {
- map[key] = p.getProperty(key)
- }
- return map
- }
-
- @Throws(IOException::class, XmlPullParserException::class)
- fun getEnumMap(path: File): Map<String, Map<String, Int>> {
- val map = mutableMapOf<String, MutableMap<String, Int>>()
-
- val xmlPullParser = XmlPullParserFactory.newInstance()
- .newPullParser()
- xmlPullParser.setInput(FileInputStream(path), null)
- var eventType = xmlPullParser.eventType
- var attr: String? = null
- while (eventType != XmlPullParser.END_DOCUMENT) {
- if (eventType == XmlPullParser.START_TAG) {
- if (TAG_ATTR == xmlPullParser.name) {
- attr = xmlPullParser.getAttributeValue(null, ATTR_NAME)
- } else if (TAG_ENUM == xmlPullParser.name || TAG_FLAG == xmlPullParser.name) {
- val name = xmlPullParser.getAttributeValue(null, ATTR_NAME)
- val value = xmlPullParser.getAttributeValue(null, ATTR_VALUE)
- // Integer.decode cannot handle "ffffffff", see JDK issue 6624867
- val i = (java.lang.Long.decode(value) as Long).toInt()
- require(attr != null)
- var attributeMap: MutableMap<String, Int>? = map[attr]
- if (attributeMap == null) {
- attributeMap = Maps.newHashMap()
- map[attr] = attributeMap
- }
- attributeMap!![name] = i
- }
- } else if (eventType == XmlPullParser.END_TAG) {
- if (TAG_ATTR == xmlPullParser.name) {
- attr = null
- }
- }
- eventType = xmlPullParser.next()
- }
-
- return map
- }
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Environment.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Environment.kt
deleted file mode 100644
index 8cfae19..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Environment.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import java.io.File
-import java.io.FileNotFoundException
-import java.nio.file.Path
-import java.nio.file.Paths
-import java.util.Locale
-import kotlin.io.path.exists
-
-data class Environment(
- val platformDir: String,
- val appTestDir: String,
- val resDir: String,
- val assetsDir: String,
- val compileSdkVersion: Int,
- val resourcePackageNames: List<String>
-) {
- init {
- val platformDirPath = Path.of(platformDir)
- if (!platformDirPath.exists()) {
- val elements = platformDirPath.nameCount
- val platform = platformDirPath.subpath(elements - 1, elements)
- val platformVersion = platform.toString().split("-").last()
- throw FileNotFoundException(
- "Missing platform version $platformVersion. " +
- "Install with sdkmanager --install \"platforms;$platform\""
- )
- }
- }
-}
-
-@Suppress("unused")
-fun androidHome() = System.getenv("ANDROID_SDK_ROOT")
- ?: System.getenv("ANDROID_HOME")
- ?: androidSdkPath()
-
-fun detectEnvironment(): Environment {
- checkInstalledJvm()
-
- val resourcesFile = File(System.getProperty("paparazzi.test.resources"))
- val configLines = resourcesFile.readLines()
-
- val appTestDir = Paths.get(System.getProperty("user.dir"))
- val androidHome = Paths.get(androidHome())
- return Environment(
- platformDir = androidHome.resolve(configLines[3]).toString(),
- appTestDir = appTestDir.toString(),
- resDir = appTestDir.resolve(configLines[1]).toString(),
- assetsDir = appTestDir.resolve(configLines[4]).toString(),
- compileSdkVersion = configLines[2].toInt(),
- resourcePackageNames = configLines[5].split(",")
- )
-}
-
-private fun androidSdkPath(): String {
- val osName = System.getProperty("os.name").lowercase(Locale.US)
- val sdkPathDir = if (osName.startsWith("windows")) {
- "\\AppData\\Local\\Android\\Sdk"
- } else if (osName.startsWith("mac")) {
- "/Library/Android/sdk"
- } else {
- "/Android/Sdk"
- }
- val homeDir = System.getProperty("user.home")
- return homeDir + sdkPathDir
-}
-
-private fun checkInstalledJvm() {
- val feature = try {
- // Runtime#version() only available as of Java 9.
- val version = Runtime::class.java.getMethod("version").invoke(null)
- // Runtime.Version#feature() only available as of Java 10.
- version.javaClass.getMethod("feature").invoke(version) as Int
- } catch (e: NoSuchMethodException) {
- -1
- }
-
- if (feature < 11) {
- throw IllegalStateException(
- "Unsupported JRE detected! Please install and run Paparazzi test suites on JDK 11+."
- )
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Flags.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Flags.kt
deleted file mode 100644
index 62c0b62..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Flags.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package app.cash.paparazzi
-
-object Flags {
- const val DEBUG_LINKED_OBJECTS = "app.cash.paparazzi.debug.linked.objects"
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt
deleted file mode 100644
index c43f4fb..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import app.cash.paparazzi.SnapshotHandler.FrameHandler
-import app.cash.paparazzi.internal.PaparazziJson
-import com.google.common.base.CharMatcher
-import java.awt.image.BufferedImage
-import java.io.File
-import java.text.SimpleDateFormat
-import java.util.Date
-import java.util.Locale
-import java.util.UUID
-import javax.imageio.ImageIO
-import okio.BufferedSink
-import okio.HashingSink
-import okio.blackholeSink
-import okio.buffer
-import okio.sink
-import okio.source
-import org.jcodec.api.awt.AWTSequenceEncoder
-
-/**
- * Creates an HTML report that avoids writing files that have already been written.
- *
- * Images and videos are named by hashes of their contents. Paparazzi won't write two images or videos with the same
- * contents. Note that the images/ directory includes the individual frames of each video.
- *
- * Runs are named by their date.
- *
- * ```
- * images
- * 088c60580f06efa95c37fd8e754074729ee74a06.png
- * 93f9a81cb594280f4b3898d90dfad8c8ea969b01.png
- * 22d37abd0841ba2a8d0bd635954baf7cbfaa269b.png
- * a4769e43cc5901ef28c0d46c46a44ea6429cbccc.png
- * videos
- * d1cddc5da2224053f2af51f4e69a76de4e61fc41.mov
- * runs
- * 20190626002322_b9854e.js
- * 20190626002345_b1e882.js
- * index.html
- * index.js
- * paparazzi.js
- * ```
- */
-class HtmlReportWriter @JvmOverloads constructor(
- private val runName: String = defaultRunName(),
- private val rootDirectory: File = File("build/reports/paparazzi"),
- snapshotRootDirectory: File = File("src/test/snapshots")
-) : SnapshotHandler {
- private val runsDirectory: File = File(rootDirectory, "runs")
- private val imagesDirectory: File = File(rootDirectory, "images")
- private val videosDirectory: File = File(rootDirectory, "videos")
-
- private val goldenImagesDirectory = File(snapshotRootDirectory, "images")
- private val goldenVideosDirectory = File(snapshotRootDirectory, "videos")
-
- private val shots = mutableListOf<Snapshot>()
-
- private val isRecording: Boolean =
- System.getProperty("paparazzi.test.record")?.toBoolean() == true
-
- init {
- runsDirectory.mkdirs()
- imagesDirectory.mkdirs()
- videosDirectory.mkdirs()
- writeStaticFiles()
- writeRunJs()
- writeIndexJs()
- }
-
- override fun newFrameHandler(
- snapshot: Snapshot,
- frameCount: Int,
- fps: Int
- ): FrameHandler {
- return object : FrameHandler {
- val hashes = mutableListOf<String>()
-
- override fun handle(image: BufferedImage) {
- hashes += writeImage(image)
- }
-
- override fun close() {
- if (hashes.isEmpty()) return
-
- val shot = if (hashes.size == 1) {
- val original = File(imagesDirectory, "${hashes[0]}.png")
- if (isRecording) {
- val goldenFile = File(goldenImagesDirectory, snapshot.toFileName("_", "png"))
- original.copyTo(goldenFile, overwrite = true)
- }
- snapshot.copy(file = original.toJsonPath())
- } else {
- val hash = writeVideo(hashes, fps)
-
- if (isRecording) {
- for ((index, frameHash) in hashes.withIndex()) {
- val originalFrame = File(imagesDirectory, "$frameHash.png")
- val frameSnapshot = snapshot.copy(name = "${snapshot.name} $index")
- val goldenFile = File(goldenImagesDirectory, frameSnapshot.toFileName("_", "png"))
- if (!goldenFile.exists()) {
- originalFrame.copyTo(goldenFile)
- }
- }
- }
- val original = File(videosDirectory, "$hash.mov")
- if (isRecording) {
- val goldenFile = File(goldenVideosDirectory, snapshot.toFileName("_", "mov"))
- if (!goldenFile.exists()) {
- original.copyTo(goldenFile)
- }
- }
- snapshot.copy(file = original.toJsonPath())
- }
-
- shots += shot
- }
- }
- }
-
- /** Returns the hash of the image. */
- private fun writeImage(image: BufferedImage): String {
- val hash = hash(image)
- val file = File(imagesDirectory, "$hash.png")
- if (!file.exists()) {
- file.writeAtomically(image)
- }
- return hash
- }
-
- /** Returns a SHA-1 hash of the pixels of [image]. */
- private fun hash(image: BufferedImage): String {
- val hashingSink = HashingSink.sha1(blackholeSink())
- hashingSink.buffer().use { sink ->
- for (y in 0 until image.height) {
- for (x in 0 until image.width) {
- sink.writeInt(image.getRGB(x, y))
- }
- }
- }
- return hashingSink.hash.hex()
- }
-
- private fun writeVideo(
- frameHashes: List<String>,
- fps: Int
- ): String {
- val hash = hash(frameHashes)
- val file = File(videosDirectory, "$hash.mov")
- if (!file.exists()) {
- val tmpFile = File(videosDirectory, "$hash.mov.tmp")
- val encoder = AWTSequenceEncoder.createSequenceEncoder(tmpFile, fps)
- for (frameHash in frameHashes) {
- val frame = ImageIO.read(File(imagesDirectory, "$frameHash.png"))
- encoder.encodeImage(frame)
- }
- encoder.finish()
- tmpFile.renameTo(file)
- }
- return hash
- }
-
- /** Returns a SHA-1 hash of [lines]. */
- private fun hash(lines: List<String>): String {
- val hashingSink = HashingSink.sha1(blackholeSink())
- hashingSink.buffer().use { sink ->
- for (hash in lines) {
- sink.writeUtf8(hash)
- sink.writeUtf8("\n")
- }
- }
- return hashingSink.hash.hex()
- }
-
- /** Release all resources and block until everything has been written to the file system. */
- override fun close() {
- writeRunJs()
- }
-
- /**
- * Emits the all runs index, which reads like JSON with an executable header.
- *
- * ```
- * window.all_runs = [
- * "20190319153912aaab",
- * "20190319153917bcfe"
- * ];
- * ```
- */
- private fun writeIndexJs() {
- val runNames = mutableListOf<String>()
- val runs = runsDirectory.list().sorted()
- for (run in runs) {
- if (run.endsWith(".js")) {
- runNames += run.substring(0, run.length - 3)
- }
- }
-
- File(rootDirectory, "index.js").writeAtomically {
- writeUtf8("window.all_runs = ")
- PaparazziJson.listOfStringsAdapter.toJson(this, runNames)
- writeUtf8(";")
- }
- }
-
- /**
- * Emits a run index, which reads like JSON with an executable header.
- *
- * ```
- * window.runs["20190319153912aaab"] = [
- * {
- * "name": "loading",
- * "testName": "app.cash.CelebrityTest#testSettings",
- * "timestamp": "2019-03-20T10:27:43Z",
- * "tags": ["redesign"],
- * "file": "loading.png"
- * },
- * {
- * "name": "error",
- * "testName": "app.cash.CelebrityTest#testSettings",
- * "timestamp": "2019-03-20T10:27:43Z",
- * "tags": ["redesign"],
- * "file": "error.png"
- * }
- * ];
- * ```
- */
- private fun writeRunJs() {
- val runJs = File(runsDirectory, "${runName.sanitizeForFilename()}.js")
- runJs.writeAtomically {
- writeUtf8("window.runs[\"$runName\"] = ")
- PaparazziJson.listOfShotsAdapter.toJson(this, shots)
- writeUtf8(";")
- }
- }
-
- private fun writeStaticFiles() {
- for (staticFile in listOf("index.html", "paparazzi.js")) {
- File(rootDirectory, staticFile).writeAtomically {
- writeAll(HtmlReportWriter::class.java.classLoader.getResourceAsStream(staticFile).source())
- }
- }
- }
-
- private fun File.writeAtomically(bufferedImage: BufferedImage) {
- val tmpFile = File(parentFile, "$name.tmp")
- ImageIO.write(bufferedImage, "PNG", tmpFile)
- delete()
- tmpFile.renameTo(this)
- }
-
- private fun File.writeAtomically(writerAction: BufferedSink.() -> Unit) {
- val tmpFile = File(parentFile, "$name.tmp")
- tmpFile.sink()
- .buffer()
- .use { sink ->
- sink.writerAction()
- }
- delete()
- tmpFile.renameTo(this)
- }
-
- private fun File.toJsonPath(): String = relativeTo(rootDirectory).invariantSeparatorsPath
-}
-
-internal fun defaultRunName(): String {
- val now = Date()
- val timestamp = SimpleDateFormat("yyyyMMddHHmmss", Locale.US).format(now)
- val token = UUID.randomUUID().toString().substring(0, 6)
- return "${timestamp}_$token"
-}
-
-internal val filenameSafeChars = CharMatcher.inRange('a', 'z')
- .or(CharMatcher.inRange('0', '9'))
- .or(CharMatcher.anyOf("_-.~@^()[]{}:;,"))
-
-internal fun String.sanitizeForFilename(): String? {
- return filenameSafeChars.negate().replaceFrom(lowercase(Locale.US), '_')
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt
deleted file mode 100644
index 2c9dec41..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import android.animation.AnimationHandler
-import android.content.Context
-import android.content.res.Resources
-import android.graphics.Bitmap
-import android.os.Handler_Delegate
-import android.os.SystemClock_Delegate
-import android.util.AttributeSet
-import android.util.DisplayMetrics
-import android.view.BridgeInflater
-import android.view.Choreographer
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams
-import android.widget.FrameLayout
-import androidx.annotation.LayoutRes
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.platform.ComposeView
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.setViewTreeLifecycleOwner
-import androidx.savedstate.SavedStateRegistry
-import androidx.savedstate.SavedStateRegistryController
-import androidx.savedstate.SavedStateRegistryOwner
-import androidx.savedstate.setViewTreeSavedStateRegistryOwner
-import app.cash.paparazzi.agent.AgentTestRule
-import app.cash.paparazzi.agent.InterceptorRegistrar
-import app.cash.paparazzi.internal.ChoreographerDelegateInterceptor
-import app.cash.paparazzi.internal.EditModeInterceptor
-import app.cash.paparazzi.internal.IInputMethodManagerInterceptor
-import app.cash.paparazzi.internal.ImageUtils
-import app.cash.paparazzi.internal.MatrixMatrixMultiplicationInterceptor
-import app.cash.paparazzi.internal.MatrixVectorMultiplicationInterceptor
-import app.cash.paparazzi.internal.PaparazziCallback
-import app.cash.paparazzi.internal.PaparazziLogger
-import app.cash.paparazzi.internal.Renderer
-import app.cash.paparazzi.internal.ResourcesInterceptor
-import app.cash.paparazzi.internal.ServiceManagerInterceptor
-import app.cash.paparazzi.internal.SessionParamsBuilder
-import app.cash.paparazzi.internal.parsers.LayoutPullParser
-import com.android.ide.common.rendering.api.RenderSession
-import com.android.ide.common.rendering.api.Result
-import com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN
-import com.android.ide.common.rendering.api.SessionParams
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode
-import com.android.internal.lang.System_Delegate
-import com.android.layoutlib.bridge.Bridge
-import com.android.layoutlib.bridge.Bridge.cleanupThread
-import com.android.layoutlib.bridge.Bridge.prepareThread
-import com.android.layoutlib.bridge.BridgeRenderSession
-import com.android.layoutlib.bridge.impl.RenderAction
-import com.android.layoutlib.bridge.impl.RenderSessionImpl
-import java.awt.image.BufferedImage
-import java.util.Date
-import java.util.concurrent.TimeUnit
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
-
-class Paparazzi @JvmOverloads constructor(
- private val environment: Environment = detectEnvironment(),
- private val deviceConfig: DeviceConfig = DeviceConfig.NEXUS_5,
- private val theme: String = "android:Theme.Material.NoActionBar.Fullscreen",
- private val renderingMode: RenderingMode = RenderingMode.NORMAL,
- private val appCompatEnabled: Boolean = true,
- private val maxPercentDifference: Double = 0.1,
- private val snapshotHandler: SnapshotHandler = determineHandler(maxPercentDifference),
- private val renderExtensions: Set<RenderExtension> = setOf()
-) : TestRule {
- private val logger = PaparazziLogger()
- private lateinit var renderSession: RenderSessionImpl
- private lateinit var bridgeRenderSession: RenderSession
- private var testName: TestName? = null
-
- val layoutInflater: LayoutInflater
- get() = RenderAction.getCurrentContext().getSystemService("layout_inflater") as BridgeInflater
-
- val resources: Resources
- get() = RenderAction.getCurrentContext().resources
-
- val context: Context
- get() = RenderAction.getCurrentContext()
-
- /**
- * The root layout that test views will be placed into. The FrameLayout is dynamically set to
- * `wrap_content` if the `renderMode` is `RenderingMode.SizeAction.SHRINK` in the appropriate
- * direction, otherwise it is set to `match_parent`.
- */
- private val contentRoot = """
- |<?xml version="1.0" encoding="utf-8"?>
- |<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- | android:layout_width="${renderingMode.horizAction.toAttrValue()}"
- | android:layout_height="${renderingMode.vertAction.toAttrValue()}"/>
- """.trimMargin()
-
- private fun RenderingMode.SizeAction.toAttrValue() =
- if (this == RenderingMode.SizeAction.SHRINK) "wrap_content" else "match_parent"
-
- override fun apply(
- base: Statement,
- description: Description
- ): Statement {
- val statement = object : Statement() {
- override fun evaluate() {
- prepare(description)
- try {
- base.evaluate()
- } finally {
- close()
- logger.assertNoErrors()
- }
- }
- }
-
- return if (!isInitialized) {
- registerFontLookupInterceptionIfResourceCompatDetected()
- registerViewEditModeInterception()
- registerMatrixMultiplyInterception()
- registerChoreographerDelegateInterception()
- registerServiceManagerInterception()
- registerIInputMethodManagerInterception()
-
- val outerRule = AgentTestRule()
- outerRule.apply(statement, description)
- } else {
- statement
- }
- }
-
- fun prepare(description: Description) {
- forcePlatformSdkVersion(environment.compileSdkVersion)
-
- val layoutlibCallback = PaparazziCallback(logger, environment.resourcePackageNames)
- layoutlibCallback.initResources()
-
- testName = description.toTestName()
-
- if (!isInitialized) {
- renderer = Renderer(environment, layoutlibCallback, logger, maxPercentDifference)
- sessionParamsBuilder = renderer.prepare()
- }
-
- sessionParamsBuilder = sessionParamsBuilder
- .copy(
- layoutPullParser = LayoutPullParser.createFromString(contentRoot),
- deviceConfig = deviceConfig,
- renderingMode = renderingMode
- )
- .withTheme(theme)
-
- val sessionParams = sessionParamsBuilder.build()
- renderSession = createRenderSession(sessionParams)
- prepareThread()
- renderSession.init(sessionParams.timeout)
- Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEVICE_STABLE)
-
- // requires LayoutInflater to be created, which is a side-effect of RenderSessionImpl.init()
- if (appCompatEnabled) {
- initializeAppCompatIfPresent()
- }
-
- bridgeRenderSession = createBridgeSession(renderSession, renderSession.inflate())
- }
-
- fun close() {
- testName = null
- renderSession.release()
- bridgeRenderSession.dispose()
- cleanupThread()
- snapshotHandler.close()
-
- renderer.dumpDelegates()
- }
-
- @Suppress("UNCHECKED_CAST")
- fun <V : View> inflate(@LayoutRes layoutId: Int): V =
- layoutInflater.inflate(layoutId, null) as V
-
- fun snapshot(name: String? = null, composable: @Composable () -> Unit) {
- val hostView = ComposeView(context)
- // During onAttachedToWindow, AbstractComposeView will attempt to resolve its parent's
- // CompositionContext, which requires first finding the "content view", then using that to
- // find a root view with a ViewTreeLifecycleOwner
- val parent = FrameLayout(context).apply { id = android.R.id.content }
- parent.addView(
- hostView,
- renderingMode.horizAction.toLayoutParams(),
- renderingMode.vertAction.toLayoutParams()
- )
- PaparazziComposeOwner.register(parent)
- hostView.setContent(composable)
-
- try {
- snapshot(parent, name)
- } finally {
- forceReleaseComposeReferenceLeaks()
- }
- }
-
- private fun RenderingMode.SizeAction.toLayoutParams() =
- if (this == RenderingMode.SizeAction.SHRINK) {
- LayoutParams.WRAP_CONTENT
- } else {
- LayoutParams.MATCH_PARENT
- }
-
- @JvmOverloads
- fun snapshot(view: View, name: String? = null) {
- takeSnapshots(view, name, 0, -1, 1)
- }
-
- @JvmOverloads
- fun gif(
- view: View,
- name: String? = null,
- start: Long = 0L,
- end: Long = 500L,
- fps: Int = 30
- ) {
- // Add one to the frame count so we get the last frame. Otherwise a 1 second, 60 FPS animation
- // our 60th frame will be at time 983 ms, and we want our last frame to be 1,000 ms. This gets
- // us 61 frames for a 1 second animation, 121 frames for a 2 second animation, etc.
- val durationMillis = (end - start).toInt()
- val frameCount = (durationMillis * fps) / 1000 + 1
- val startNanos = TimeUnit.MILLISECONDS.toNanos(start)
- takeSnapshots(view, name, startNanos, fps, frameCount)
- }
-
- fun unsafeUpdateConfig(
- deviceConfig: DeviceConfig? = null,
- theme: String? = null,
- renderingMode: RenderingMode? = null
- ) {
- require(deviceConfig != null || theme != null || renderingMode != null) {
- "Calling unsafeUpdateConfig requires at least one non-null argument."
- }
-
- renderSession.release()
- bridgeRenderSession.dispose()
- cleanupThread()
-
- sessionParamsBuilder = sessionParamsBuilder
- .copy(
- // Required to reset underlying parser stream
- layoutPullParser = LayoutPullParser.createFromString(contentRoot)
- )
-
- if (deviceConfig != null) {
- sessionParamsBuilder = sessionParamsBuilder.copy(deviceConfig = deviceConfig)
- }
-
- if (theme != null) {
- sessionParamsBuilder = sessionParamsBuilder.withTheme(theme)
- }
-
- if (renderingMode != null) {
- sessionParamsBuilder = sessionParamsBuilder.copy(renderingMode = renderingMode)
- }
-
- val sessionParams = sessionParamsBuilder.build()
- renderSession = createRenderSession(sessionParams)
- prepareThread()
- renderSession.init(sessionParams.timeout)
- Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEVICE_STABLE)
- bridgeRenderSession = createBridgeSession(renderSession, renderSession.inflate())
- }
-
- private fun takeSnapshots(
- view: View,
- name: String?,
- startNanos: Long,
- fps: Int,
- frameCount: Int
- ) {
- val snapshot = Snapshot(name, testName!!, Date())
-
- val frameHandler = snapshotHandler.newFrameHandler(snapshot, frameCount, fps)
- frameHandler.use {
- val viewGroup = bridgeRenderSession.rootViews[0].viewObject as ViewGroup
- val modifiedView = renderExtensions.fold(view) { view, renderExtension ->
- renderExtension.renderView(view)
- }
-
- System_Delegate.setBootTimeNanos(0L)
- try {
- withTime(0L) {
- // Initialize the choreographer at time=0.
- }
-
- viewGroup.addView(modifiedView)
- for (frame in 0 until frameCount) {
- val nowNanos = (startNanos + (frame * 1_000_000_000.0 / fps)).toLong()
- withTime(nowNanos) {
- val result = renderSession.render(true)
- if (result.status == ERROR_UNKNOWN) {
- throw result.exception
- }
-
- val image = bridgeRenderSession.image
- frameHandler.handle(scaleImage(image))
- }
- }
- } finally {
- viewGroup.removeView(modifiedView)
- AnimationHandler.sAnimatorHandler.set(null)
- }
- }
- }
-
- private fun withTime(
- timeNanos: Long,
- block: () -> Unit
- ) {
- val frameNanos = TIME_OFFSET_NANOS + timeNanos
-
- // Execute the block at the requested time.
- System_Delegate.setNanosTime(frameNanos)
-
- val choreographer = Choreographer.getInstance()
- val areCallbacksRunningField = choreographer::class.java.getDeclaredField("mCallbacksRunning")
- areCallbacksRunningField.isAccessible = true
-
- try {
- areCallbacksRunningField.setBoolean(choreographer, true)
-
- // https://android.googlesource.com/platform/frameworks/layoutlib/+/d58aa4703369e109b24419548f38b422d5a44738/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java#171
- // BridgeRenderSession.executeCallbacks aggressively tears down the main Looper and BridgeContext, so we call the static delegates ourselves.
- Handler_Delegate.executeCallbacks()
- val currentTimeMs = SystemClock_Delegate.uptimeMillis()
- val choreographerCallbacks =
- RenderAction.getCurrentContext().sessionInteractiveData.choreographerCallbacks
- choreographerCallbacks.execute(currentTimeMs, Bridge.getLog())
-
- block()
- } catch (e: Throwable) {
- Bridge.getLog().error("broken", "Failed executing Choreographer#doFrame", e, null, null)
- throw e
- } finally {
- areCallbacksRunningField.setBoolean(choreographer, false)
- }
- }
-
- private fun createRenderSession(sessionParams: SessionParams): RenderSessionImpl {
- val renderSession = RenderSessionImpl(sessionParams)
- renderSession.setElapsedFrameTimeNanos(0L)
- RenderSessionImpl::class.java
- .getDeclaredField("mFirstFrameExecuted")
- .apply {
- isAccessible = true
- set(renderSession, true)
- }
- return renderSession
- }
-
- private fun createBridgeSession(
- renderSession: RenderSessionImpl,
- result: Result
- ): BridgeRenderSession {
- try {
- val bridgeSessionClass = Class.forName("com.android.layoutlib.bridge.BridgeRenderSession")
- val constructor =
- bridgeSessionClass.getDeclaredConstructor(RenderSessionImpl::class.java, Result::class.java)
- constructor.isAccessible = true
- return constructor.newInstance(renderSession, result) as BridgeRenderSession
- } catch (e: Exception) {
- throw RuntimeException(e)
- }
- }
-
- private fun scaleImage(image: BufferedImage): BufferedImage {
- val scale = ImageUtils.getThumbnailScale(image)
- // Only scale images down so we don't waste storage space enlarging smaller layouts.
- return if (scale < 1f) ImageUtils.scale(image, scale, scale) else image
- }
-
- private fun Description.toTestName(): TestName {
- val fullQualifiedName = className
- val packageName = fullQualifiedName.substringBeforeLast('.', missingDelimiterValue = "")
- val className = fullQualifiedName.substringAfterLast('.')
- return TestName(packageName, className, methodName)
- }
-
- private fun forcePlatformSdkVersion(compileSdkVersion: Int) {
- val buildVersionClass = try {
- Paparazzi::class.java.classLoader.loadClass("android.os.Build\$VERSION")
- } catch (e: ClassNotFoundException) {
- // Project unit tests don't load Android platform code
- return
- }
- buildVersionClass
- .getFieldReflectively("SDK_INT")
- .setStaticValue(compileSdkVersion)
- }
-
- private fun initializeAppCompatIfPresent() {
- lateinit var appCompatDelegateClass: Class<*>
- try {
- // See androidx.appcompat.widget.AppCompatDrawableManager#preload()
- val appCompatDrawableManagerClass =
- Class.forName("androidx.appcompat.widget.AppCompatDrawableManager")
- val preloadMethod = appCompatDrawableManagerClass.getMethod("preload")
- preloadMethod.invoke(null)
-
- appCompatDelegateClass = Class.forName("androidx.appcompat.app.AppCompatDelegate")
- } catch (e: ClassNotFoundException) {
- logger.verbose("AppCompat not found on classpath")
- return
- }
-
- // See androidx.appcompat.app.AppCompatDelegateImpl#installViewFactory()
- if (layoutInflater.factory == null) {
- layoutInflater.factory2 = object : LayoutInflater.Factory2 {
- override fun onCreateView(
- parent: View?,
- name: String,
- context: Context,
- attrs: AttributeSet
- ): View? {
- val appCompatViewInflaterClass =
- Class.forName("androidx.appcompat.app.AppCompatViewInflater")
-
- val createViewMethod = appCompatViewInflaterClass
- .getDeclaredMethod(
- "createView",
- View::class.java,
- String::class.java,
- Context::class.java,
- AttributeSet::class.java,
- Boolean::class.javaPrimitiveType,
- Boolean::class.javaPrimitiveType,
- Boolean::class.javaPrimitiveType,
- Boolean::class.javaPrimitiveType
- )
- .apply { isAccessible = true }
-
- val inheritContext = true
- val readAndroidTheme = true
- val readAppTheme = true
- val wrapContext = true
-
- val newAppCompatViewInflaterInstance = appCompatViewInflaterClass
- .getConstructor()
- .newInstance()
-
- return createViewMethod.invoke(
- newAppCompatViewInflaterInstance, parent, name, context, attrs,
- inheritContext, readAndroidTheme, readAppTheme, wrapContext
- ) as View?
- }
-
- override fun onCreateView(
- name: String,
- context: Context,
- attrs: AttributeSet
- ): View? = onCreateView(null, name, context, attrs)
- }
- } else {
- if (!appCompatDelegateClass.isAssignableFrom(layoutInflater.factory2::class.java)) {
- throw IllegalStateException(
- "The LayoutInflater already has a Factory installed so we can not install AppCompat's"
- )
- }
- }
- }
-
- /**
- * Current workaround for supporting custom fonts when constructing views in code. This check
- * may be used or expanded to support other cases requiring similar method interception
- * techniques.
- *
- * See:
- * https://github.com/cashapp/paparazzi/issues/119
- * https://issuetracker.google.com/issues/156065472
- */
- private fun registerFontLookupInterceptionIfResourceCompatDetected() {
- try {
- val resourcesCompatClass = Class.forName("androidx.core.content.res.ResourcesCompat")
- InterceptorRegistrar.addMethodInterceptor(
- resourcesCompatClass,
- "getFont",
- ResourcesInterceptor::class.java
- )
- } catch (e: ClassNotFoundException) {
- logger.verbose("ResourceCompat not found on classpath")
- }
- }
-
- private fun registerServiceManagerInterception() {
- val serviceManager = Class.forName("android.os.ServiceManager")
- InterceptorRegistrar.addMethodInterceptor(
- serviceManager,
- "getServiceOrThrow",
- ServiceManagerInterceptor::class.java
- )
- }
-
- private fun registerIInputMethodManagerInterception() {
- val iimm = Class.forName("com.android.internal.view.IInputMethodManager\$Stub")
- InterceptorRegistrar.addMethodInterceptor(
- iimm,
- "asInterface",
- IInputMethodManagerInterceptor::class.java
- )
- }
-
- private fun registerViewEditModeInterception() {
- val viewClass = Class.forName("android.view.View")
- InterceptorRegistrar.addMethodInterceptor(
- viewClass,
- "isInEditMode",
- EditModeInterceptor::class.java
- )
- }
-
- private fun registerMatrixMultiplyInterception() {
- val matrixClass = Class.forName("android.opengl.Matrix")
- InterceptorRegistrar.addMethodInterceptors(
- matrixClass,
- setOf(
- "multiplyMM" to MatrixMatrixMultiplicationInterceptor::class.java,
- "multiplyMV" to MatrixVectorMultiplicationInterceptor::class.java
- )
- )
- }
-
- private fun registerChoreographerDelegateInterception() {
- val choreographerDelegateClass = Class.forName("android.view.Choreographer_Delegate")
- InterceptorRegistrar.addMethodInterceptor(
- choreographerDelegateClass,
- "getFrameTimeNanos",
- ChoreographerDelegateInterceptor::class.java
- )
- }
-
- private fun forceReleaseComposeReferenceLeaks() {
- // AndroidUiDispatcher is backed by a Handler, by executing one last time
- // we give the dispatcher the ability to clean-up / release its callbacks.
- executeHandlerCallbacks()
- }
-
- private fun executeHandlerCallbacks() {
- // Avoid ConcurrentModificationException in
- // RenderAction.currentContext.sessionInteractiveData.handlerMessageQueue.runnablesMap which is a WeakHashMap
- // https://android.googlesource.com/platform/tools/adt/idea/+/c331c9b2f4334748c55c29adec3ad1cd67e45df2/designer/src/com/android/tools/idea/uibuilder/scene/LayoutlibSceneManager.java#1558
- synchronized(this) {
- // https://android.googlesource.com/platform/frameworks/layoutlib/+/d58aa4703369e109b24419548f38b422d5a44738/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java#171
- // BridgeRenderSession.executeCallbacks aggressively tears down the main Looper and BridgeContext, so we call the static delegates ourselves.
- Handler_Delegate.executeCallbacks()
- }
- }
-
- private class PaparazziComposeOwner private constructor() :
- LifecycleOwner, SavedStateRegistryOwner {
- private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
- private val savedStateRegistryController = SavedStateRegistryController.create(this)
-
- override val lifecycle: Lifecycle
- get() = lifecycleRegistry
- override val savedStateRegistry: SavedStateRegistry =
- savedStateRegistryController.savedStateRegistry
-
- companion object {
- fun register(view: View) {
- val owner = PaparazziComposeOwner()
- owner.savedStateRegistryController.performRestore(null)
- owner.lifecycleRegistry.currentState = Lifecycle.State.CREATED
- view.setViewTreeLifecycleOwner(owner)
- view.setViewTreeSavedStateRegistryOwner(owner)
- }
- }
- }
-
- companion object {
- /** The choreographer doesn't like 0 as a frame time, so start an hour later. */
- internal val TIME_OFFSET_NANOS = TimeUnit.HOURS.toNanos(1L)
-
- internal lateinit var renderer: Renderer
- internal val isInitialized get() = ::renderer.isInitialized
-
- internal lateinit var sessionParamsBuilder: SessionParamsBuilder
-
- private val isVerifying: Boolean =
- System.getProperty("paparazzi.test.verify")?.toBoolean() == true
-
- private fun determineHandler(maxPercentDifference: Double): SnapshotHandler =
- if (isVerifying) {
- SnapshotVerifier(maxPercentDifference)
- } else {
- HtmlReportWriter()
- }
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt
deleted file mode 100644
index 15617f0..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package app.cash.paparazzi
-
-import java.lang.reflect.Field
-import java.lang.reflect.Modifier
-import java.security.PrivilegedAction
-import sun.misc.Unsafe
-
-/**
- * Inspired by and ported from:
- * https://github.com/powermock/powermock/commit/fc092c5d7e339d01e079184a2a0e88b5c46fc0e8
- * https://github.com/powermock/powermock/commit/bd92bcc5329c4981cf09dece5c3eafcf92fe49ff
- */
-internal fun Class<*>.getFieldReflectively(fieldName: String): Field =
- try {
- this.getDeclaredField(fieldName).also { it.isAccessible = true }
- } catch (e: NoSuchFieldException) {
- throw RuntimeException("Field '$fieldName' was not found in class $name.")
- }
-
-internal fun Field.setStaticValue(value: Any) {
- try {
- this.isAccessible = true
- val isFinalModifierPresent = this.modifiers and Modifier.FINAL == Modifier.FINAL
- if (isFinalModifierPresent) {
- @Suppress("DEPRECATION")
- java.security.AccessController.doPrivileged<Any?>(
- PrivilegedAction {
- try {
- val unsafe = Unsafe::class.java.getFieldReflectively("theUnsafe").get(null) as Unsafe
- val offset = unsafe.staticFieldOffset(this)
- val base = unsafe.staticFieldBase(this)
- unsafe.setFieldValue(this, base, offset, value)
- null
- } catch (t: Throwable) {
- throw RuntimeException(t)
- }
- }
- )
- } else {
- this.set(null, value)
- }
- } catch (ex: SecurityException) {
- throw RuntimeException(ex)
- } catch (ex: IllegalAccessException) {
- throw RuntimeException(ex)
- } catch (ex: IllegalArgumentException) {
- throw RuntimeException(ex)
- }
-}
-
-internal fun Unsafe.setFieldValue(field: Field, base: Any, offset: Long, value: Any) =
- when (field.type) {
- Integer.TYPE -> this.putInt(base, offset, (value as Int))
- java.lang.Short.TYPE -> this.putShort(base, offset, (value as Short))
- java.lang.Long.TYPE -> this.putLong(base, offset, (value as Long))
- java.lang.Byte.TYPE -> this.putByte(base, offset, (value as Byte))
- java.lang.Boolean.TYPE -> this.putBoolean(base, offset, (value as Boolean))
- java.lang.Float.TYPE -> this.putFloat(base, offset, (value as Float))
- java.lang.Double.TYPE -> this.putDouble(base, offset, (value as Double))
- Character.TYPE -> this.putChar(base, offset, (value as Char))
- else -> this.putObject(base, offset, value)
- }
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/RenderExtension.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/RenderExtension.kt
deleted file mode 100644
index d0d12b2..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/RenderExtension.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import android.view.View
-
-/**
- * An extension for overlaying additional information on top of each rendered frame.
- */
-interface RenderExtension {
- /**
- * Allows this extension to modify the view hierarchy represented by [contentView].
- *
- * Returns the root view of the modified hierarchy.
- */
- fun renderView(contentView: View): View
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Snapshot.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Snapshot.kt
deleted file mode 100644
index 85501f7..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Snapshot.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import com.squareup.moshi.JsonClass
-import java.util.Date
-import java.util.Locale
-
-@JsonClass(generateAdapter = true)
-data class Snapshot(
- val name: String?,
- val testName: TestName,
- val timestamp: Date,
- val tags: List<String> = listOf(),
- val file: String? = null
-)
-
-internal fun Snapshot.toFileName(
- delimiter: String = "_",
- extension: String
-): String {
- val formattedLabel = if (name != null) {
- "$delimiter${name.lowercase(Locale.US).replace("\\s".toRegex(), delimiter)}"
- } else {
- ""
- }
- return "${testName.packageName}${delimiter}${testName.className}" +
- "${delimiter}${testName.methodName}$formattedLabel.$extension"
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/SnapshotHandler.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/SnapshotHandler.kt
deleted file mode 100644
index 5067f25..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/SnapshotHandler.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import java.awt.image.BufferedImage
-import java.io.Closeable
-
-interface SnapshotHandler : Closeable {
- fun newFrameHandler(
- snapshot: Snapshot,
- frameCount: Int,
- fps: Int
- ): FrameHandler
-
- interface FrameHandler : Closeable {
- fun handle(image: BufferedImage)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/SnapshotVerifier.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/SnapshotVerifier.kt
deleted file mode 100644
index 564cd2e..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/SnapshotVerifier.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import app.cash.paparazzi.SnapshotHandler.FrameHandler
-import app.cash.paparazzi.internal.ImageUtils
-import java.awt.image.BufferedImage
-import java.io.File
-import javax.imageio.ImageIO
-
-class SnapshotVerifier @JvmOverloads constructor(
- private val maxPercentDifference: Double,
- rootDirectory: File = File("src/test/snapshots")
-) : SnapshotHandler {
- private val imagesDirectory: File = File(rootDirectory, "images")
- private val videosDirectory: File = File(rootDirectory, "videos")
-
- init {
- imagesDirectory.mkdirs()
- videosDirectory.mkdirs()
- }
-
- override fun newFrameHandler(
- snapshot: Snapshot,
- frameCount: Int,
- fps: Int
- ): FrameHandler {
- return object : FrameHandler {
- override fun handle(image: BufferedImage) {
- // Note: does not handle videos or its frames at the moment
- val expected = File(imagesDirectory, snapshot.toFileName(extension = "png"))
- if (!expected.exists()) {
- throw AssertionError("File $expected does not exist")
- }
-
- val goldenImage = ImageIO.read(expected)
- ImageUtils.assertImageSimilar(
- relativePath = expected.path,
- image = image,
- goldenImage = goldenImage,
- maxPercentDifferent = maxPercentDifference
- )
- }
-
- override fun close() = Unit
- }
- }
-
- override fun close() = Unit
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/TestName.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/TestName.kt
deleted file mode 100644
index 2ab7963..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/TestName.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-data class TestName(
- val packageName: String,
- val className: String,
- val methodName: String
-)
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtension.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtension.kt
deleted file mode 100644
index f6f16aa..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtension.kt
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.accessibility
-
-import android.graphics.drawable.GradientDrawable
-import android.graphics.drawable.LayerDrawable
-import android.util.TypedValue
-import android.view.View
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import android.widget.TextView
-import app.cash.paparazzi.RenderExtension
-import app.cash.paparazzi.accessibility.RenderSettings.DEFAULT_DESCRIPTION_BACKGROUND_COLOR
-import app.cash.paparazzi.accessibility.RenderSettings.DEFAULT_RECT_SIZE
-import app.cash.paparazzi.accessibility.RenderSettings.DEFAULT_RENDER_ALPHA
-import app.cash.paparazzi.accessibility.RenderSettings.DEFAULT_TEXT_COLOR
-import app.cash.paparazzi.accessibility.RenderSettings.DEFAULT_TEXT_SIZE
-import app.cash.paparazzi.accessibility.RenderSettings.getColor
-import app.cash.paparazzi.accessibility.RenderSettings.toColorInt
-import app.cash.paparazzi.accessibility.RenderSettings.withAlpha
-
-class AccessibilityRenderExtension : RenderExtension {
- override fun renderView(
- contentView: View
- ): View {
- val accessibilityViews = contentView.findAccessibilityViews()
- accessibilityViews.forEach { view ->
- val color = getColor(view)
- val colorInt = color.toColorInt()
-
- val colorDrawable = GradientDrawable(
- GradientDrawable.Orientation.TOP_BOTTOM,
- intArrayOf(colorInt, colorInt)
- ).apply {
- setStroke(2, color.withAlpha(DEFAULT_RENDER_ALPHA * 2).toColorInt())
- }
-
- view.foreground = view.foreground?.let { drawable ->
- // If there is an existing foreground layer the color on top of it.
- LayerDrawable(arrayOf(drawable, colorDrawable))
- } ?: colorDrawable
- }
-
- return LinearLayout(contentView.context).apply {
- orientation = LinearLayout.HORIZONTAL
- weightSum = 2f
- layoutParams = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT
- )
-
- val contentLayoutParams = contentView.layoutParams ?: generateLayoutParams(null)
- addView(
- contentView,
- LinearLayout.LayoutParams(
- contentLayoutParams.width,
- contentLayoutParams.height,
- 1f
- )
- )
- addView(
- buildAccessibilityView(contentView),
- LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT,
- 1f
- )
- )
- }
- }
-
- private fun View.findAccessibilityViews(): List<View> {
- val accessibilityViews = mutableListOf<View>()
- if (isImportantForAccessibility && !iterableTextForAccessibility.isNullOrBlank()) {
- accessibilityViews.add(this)
- }
-
- if (this is ViewGroup) {
- (0 until childCount).forEach {
- accessibilityViews += getChildAt(it).findAccessibilityViews()
- }
- }
-
- return accessibilityViews
- }
-
- private fun buildAccessibilityView(contentView: View): View {
- val linearLayout = LinearLayout(contentView.context).apply {
- orientation = LinearLayout.VERTICAL
- setBackgroundColor(DEFAULT_DESCRIPTION_BACKGROUND_COLOR.toColorInt())
- }
-
- fun renderAccessibility(view: View) {
- if (view.isImportantForAccessibility && !view.iterableTextForAccessibility.isNullOrBlank()) {
- linearLayout.addView(buildAccessibilityRow(view, view.iterableTextForAccessibility))
- }
-
- if (view is ViewGroup) {
- (0 until view.childCount).forEach {
- renderAccessibility(view.getChildAt(it))
- }
- }
- }
-
- renderAccessibility(contentView)
- return linearLayout
- }
-
- private fun buildAccessibilityRow(view: View, iterableTextForAccessibility: CharSequence): View {
- val context = view.context
- val color = getColor(view).toColorInt()
- val margin = view.dip(8)
- val innerMargin = view.dip(4)
-
- return LinearLayout(context).apply {
- orientation = LinearLayout.HORIZONTAL
- layoutParams = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- )
- setPaddingRelative(margin, innerMargin, margin, innerMargin)
-
- addView(
- View(context).apply {
- layoutParams = ViewGroup.LayoutParams(dip(DEFAULT_RECT_SIZE), dip(DEFAULT_RECT_SIZE))
- background = GradientDrawable(
- GradientDrawable.Orientation.TOP_BOTTOM,
- intArrayOf(color, color)
- ).apply {
- cornerRadius = dip(DEFAULT_RECT_SIZE / 4f)
- }
- setPaddingRelative(innerMargin, innerMargin, innerMargin, innerMargin)
- }
- )
- addView(
- TextView(context).apply {
- layoutParams = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- )
- text = iterableTextForAccessibility
- textSize = DEFAULT_TEXT_SIZE
- setTextColor(DEFAULT_TEXT_COLOR.toColorInt())
- setPaddingRelative(innerMargin, 0, innerMargin, 0)
- }
- )
- }
- }
-}
-
-private fun View.dip(value: Float): Float =
- TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- value,
- resources.displayMetrics
- )
-
-private fun View.dip(value: Int): Int = dip(value.toFloat()).toInt()
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/accessibility/RenderSettings.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/accessibility/RenderSettings.kt
deleted file mode 100644
index 768fc6e..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/accessibility/RenderSettings.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.accessibility
-
-import android.view.View
-import java.awt.Color
-
-internal object RenderSettings {
- const val DEFAULT_RENDER_ALPHA = 40
- val DEFAULT_RENDER_COLORS = listOf(
- Color.RED,
- Color.GREEN,
- Color.BLUE,
- Color.YELLOW,
- Color.ORANGE,
- Color.MAGENTA,
- Color.CYAN,
- Color.PINK
- )
- val DEFAULT_TEXT_COLOR: Color = Color.BLACK
- val DEFAULT_DESCRIPTION_BACKGROUND_COLOR: Color = Color.WHITE
- const val DEFAULT_TEXT_SIZE: Float = 10f
- const val DEFAULT_RECT_SIZE: Int = 16
-
- private val colorMap = mutableMapOf<Int, Color>()
-
- fun getColor(view: View): Color {
- val key = "${view::class.simpleName}(${view.iterableTextForAccessibility})"
- return getColor(key)
- }
-
- private fun getColor(key: String): Color {
- val hashCode = key.hashCode()
- return colorMap.getOrPut(hashCode) {
- nextColor(hashCode).withAlpha(DEFAULT_RENDER_ALPHA)
- }
- }
-
- private fun nextColor(hashCode: Int): Color {
- return DEFAULT_RENDER_COLORS[colorIndex(hashCode)]
- }
-
- private fun colorIndex(hashCode: Int): Int {
- val size = DEFAULT_RENDER_COLORS.size
- val i = hashCode % size
- return if (i < 0) i + size else i
- }
-
- internal fun Color.toColorInt(): Int =
- android.graphics.Color.argb(alpha, red, green, blue)
-
- internal fun Color.withAlpha(alpha: Int): Color {
- return Color(red, green, blue, alpha)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ChoreographerDelegateInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ChoreographerDelegateInterceptor.kt
deleted file mode 100644
index 57b7bf1..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ChoreographerDelegateInterceptor.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package app.cash.paparazzi.internal
-
-import android.view.Choreographer
-import com.android.internal.lang.System_Delegate
-
-object ChoreographerDelegateInterceptor {
- @Suppress("unused")
- @JvmStatic
- fun intercept(
- @Suppress("UNUSED_PARAMETER") choreographer: Choreographer
- ): Long = System_Delegate.nanoTime()
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/EditModeInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/EditModeInterceptor.kt
deleted file mode 100644
index c464a04..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/EditModeInterceptor.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package app.cash.paparazzi.internal
-
-object EditModeInterceptor {
- @JvmStatic
- fun intercept(): Boolean = false
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/Gc.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/Gc.kt
deleted file mode 100644
index 5bbd25c..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/Gc.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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 app.cash.paparazzi.internal
-
-import java.lang.ref.WeakReference
-
-internal object Gc {
- fun gc() {
- // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
- var obj: Any? = Any()
- val ref = WeakReference<Any>(obj)
-
- @Suppress("UNUSED_VAlUE")
- obj = null
- while (ref.get() != null) {
- System.gc()
- System.runFinalization()
- }
-
- System.gc()
- System.runFinalization()
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/IInputMethodManagerInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/IInputMethodManagerInterceptor.kt
deleted file mode 100644
index 1908949..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/IInputMethodManagerInterceptor.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package app.cash.paparazzi.internal
-
-import android.os.IBinder
-import com.android.internal.view.IInputMethodManager
-
-/**
- * With [ServiceManagerInterceptor] returning null for the service, we must override the logic
- * in [com.android.internal.view.IInputMethodManager.Stub.asInterface] to return the default
- * implementation of [IInputMethodManager].
- */
-object IInputMethodManagerInterceptor {
- @Suppress("unused")
- @JvmStatic
- fun interceptAsInterface(@Suppress("UNUSED_PARAMETER") obj: IBinder?): IInputMethodManager =
- IInputMethodManager.Default()
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt
deleted file mode 100644
index 8e7111c..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2016 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 app.cash.paparazzi.internal
-
-import java.awt.AlphaComposite
-import java.awt.Color
-import java.awt.Graphics2D
-import java.awt.RenderingHints.KEY_ANTIALIASING
-import java.awt.RenderingHints.KEY_INTERPOLATION
-import java.awt.RenderingHints.KEY_RENDERING
-import java.awt.RenderingHints.VALUE_ANTIALIAS_ON
-import java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR
-import java.awt.RenderingHints.VALUE_RENDER_QUALITY
-import java.awt.image.BufferedImage
-import java.awt.image.BufferedImage.TYPE_INT_ARGB
-import java.io.File
-import java.io.File.separatorChar
-import java.io.IOException
-import javax.imageio.ImageIO
-import kotlin.math.max
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
-
-/**
- * Utilities related to image processing.
- */
-internal object ImageUtils {
- /**
- * Normally, this test will fail when there is a missing thumbnail. However, when
- * you create creating a new test, it's useful to be able to turn this off such that
- * you can generate all the missing thumbnails in one go, rather than having to run
- * the test repeatedly to get to each new render assertion generating its thumbnail.
- */
- private val FAIL_ON_MISSING_THUMBNAIL = true
-
- private const val THUMBNAIL_SIZE = 1000
-
- /** Directory where to write the thumbnails and deltas. */
- private val failureDir: File
- get() {
- val workingDirString = System.getProperty("user.dir")
- val failureDir = File(workingDirString, "out/failures")
- failureDir.mkdirs()
- return failureDir
- }
-
- @Throws(IOException::class)
- fun requireSimilar(
- relativePath: String,
- image: BufferedImage,
- maxPercentDifference: Double
- ) {
- val scale = getThumbnailScale(image)
- val thumbnail = scale(image, scale, scale)
-
- val `is` = ImageUtils::class.java.classLoader.getResourceAsStream(relativePath)
- if (`is` ==
- null
- ) {
- var message = "Unable to load golden thumbnail: $relativePath\n"
- message = saveImageAndAppendMessage(thumbnail, message, relativePath)
- if (FAIL_ON_MISSING_THUMBNAIL) {
- fail(message)
- } else {
- println(message)
- }
- } else {
- try {
- val goldenImage = ImageIO.read(`is`)
- assertImageSimilar(
- relativePath,
- goldenImage,
- thumbnail,
- maxPercentDifference
- )
- } finally {
- `is`.close()
- }
- }
- }
-
- @Throws(IOException::class)
- fun assertImageSimilar(
- relativePath: String,
- goldenImage: BufferedImage,
- image: BufferedImage,
- maxPercentDifferent: Double
- ) {
- @Suppress("NAME_SHADOWING") var goldenImage = goldenImage
- if (goldenImage.type != TYPE_INT_ARGB) {
- val temp = BufferedImage(
- goldenImage.width,
- goldenImage.height,
- TYPE_INT_ARGB
- )
- temp.graphics.drawImage(goldenImage, 0, 0, null)
- goldenImage = temp
- }
- assertEquals(TYPE_INT_ARGB.toLong(), goldenImage.type.toLong())
-
- val imageWidth = Math.min(goldenImage.width, image.width)
- val imageHeight = Math.min(goldenImage.height, image.height)
-
- // Blur the images to account for the scenarios where there are pixel
- // differences
- // in where a sharp edge occurs
- // goldenImage = blur(goldenImage, 6);
- // image = blur(image, 6);
-
- val width = 3 * imageWidth
- val deltaImage = BufferedImage(width, imageHeight, TYPE_INT_ARGB)
- val g = deltaImage.graphics
-
- // Compute delta map
- var delta: Long = 0
- for (y in 0 until imageHeight) {
- for (x in 0 until imageWidth) {
- val goldenRgb = goldenImage.getRGB(x, y)
- val rgb = image.getRGB(x, y)
- if (goldenRgb == rgb) {
- deltaImage.setRGB(imageWidth + x, y, 0x00808080)
- continue
- }
-
- // If the pixels have no opacity, don't delta colors at all
- if (goldenRgb and -0x1000000 == 0 && rgb and -0x1000000 == 0) {
- deltaImage.setRGB(imageWidth + x, y, 0x00808080)
- continue
- }
-
- val deltaR = (rgb and 0xFF0000).ushr(16) - (goldenRgb and 0xFF0000).ushr(16)
- val newR = 128 + deltaR and 0xFF
- val deltaG = (rgb and 0x00FF00).ushr(8) - (goldenRgb and 0x00FF00).ushr(8)
- val newG = 128 + deltaG and 0xFF
- val deltaB = (rgb and 0x0000FF) - (goldenRgb and 0x0000FF)
- val newB = 128 + deltaB and 0xFF
-
- val avgAlpha =
- ((goldenRgb and -0x1000000).ushr(24) + (rgb and -0x1000000).ushr(24)) / 2 shl 24
-
- val newRGB = avgAlpha or (newR shl 16) or (newG shl 8) or newB
- deltaImage.setRGB(imageWidth + x, y, newRGB)
-
- delta += Math.abs(deltaR)
- .toLong()
- delta += Math.abs(deltaG)
- .toLong()
- delta += Math.abs(deltaB)
- .toLong()
- }
- }
-
- // 3 different colors, 256 color levels
- val total = imageHeight.toLong() * imageWidth.toLong() * 3L * 256L
- val percentDifference = (delta * 100 / total.toDouble()).toFloat()
-
- var error: String? = null
- val imageName = getName(relativePath)
- if (percentDifference > maxPercentDifferent) {
- error = String.format("Images differ (by %.1f%%)", percentDifference)
- } else if (Math.abs(goldenImage.width - image.width) >= 2) {
- error = "Widths differ too much for " + imageName + ": " +
- goldenImage.width + "x" + goldenImage.height +
- "vs" + image.width + "x" + image.height
- } else if (Math.abs(goldenImage.height - image.height) >= 2) {
- error = "Heights differ too much for " + imageName + ": " +
- goldenImage.width + "x" + goldenImage.height +
- "vs" + image.width + "x" + image.height
- }
-
- if (error != null) {
- // Expected on the left
- // Golden on the right
- g.drawImage(goldenImage, 0, 0, null)
- g.drawImage(image, 2 * imageWidth, 0, null)
-
- // Labels
- if (imageWidth > 80) {
- g.color = Color.RED
- g.drawString("Expected", 10, 20)
- g.drawString("Actual", 2 * imageWidth + 10, 20)
- }
-
- val output = File(failureDir, "delta-$imageName")
- if (output.exists()) {
- val deleted = output.delete()
- assertTrue(deleted)
- }
- ImageIO.write(deltaImage, "PNG", output)
- error += " - see details in file://" + output.path + "\n"
- error = saveImageAndAppendMessage(image, error, relativePath)
- println(error)
- fail(error)
- }
-
- g.dispose()
- }
-
- /**
- * Resize the given image
- *
- * @param source the image to be scaled
- * @param xScale x scale
- * @param yScale y scale
- * @return the scaled image
- */
- fun scale(
- source: BufferedImage,
- xScale: Double,
- yScale: Double
- ): BufferedImage {
- @Suppress("NAME_SHADOWING") var source = source
-
- var sourceWidth = source.width
- var sourceHeight = source.height
- val destWidth = Math.max(1, (xScale * sourceWidth).toInt())
- val destHeight = Math.max(1, (yScale * sourceHeight).toInt())
- var imageType = source.type
- if (imageType == BufferedImage.TYPE_CUSTOM) {
- imageType = BufferedImage.TYPE_INT_ARGB
- }
- if (xScale > 0.5 && yScale > 0.5) {
- val scaled = BufferedImage(destWidth, destHeight, imageType)
- val g2 = scaled.createGraphics()
- g2.composite = AlphaComposite.Src
- g2.color = Color(0, true)
- g2.fillRect(0, 0, destWidth, destHeight)
- if (xScale == 1.0 && yScale == 1.0) {
- g2.drawImage(source, 0, 0, null)
- } else {
- setRenderingHints(g2)
- g2.drawImage(source, 0, 0, destWidth, destHeight, 0, 0, sourceWidth, sourceHeight, null)
- }
- g2.dispose()
- return scaled
- } else {
- // When creating a thumbnail, using the above code doesn't work very well;
- // you get some visible artifacts, especially for text. Instead use the
- // technique of repeatedly scaling the image into half; this will cause
- // proper averaging of neighboring pixels, and will typically (for the kinds
- // of screen sizes used by this utility method in the layout editor) take
- // about 3-4 iterations to get the result since we are logarithmically reducing
- // the size. Besides, each successive pass in operating on much fewer pixels
- // (a reduction of 4 in each pass).
- //
- // However, we may not be resizing to a size that can be reached exactly by
- // successively diving in half. Therefore, once we're within a factor of 2 of
- // the final size, we can do a resize to the exact target size.
- // However, we can get even better results if we perform this final resize
- // up front. Let's say we're going from width 1000 to a destination width of 85.
- // The first approach would cause a resize from 1000 to 500 to 250 to 125, and
- // then a resize from 125 to 85. That last resize can distort/blur a lot.
- // Instead, we can start with the destination width, 85, and double it
- // successfully until we're close to the initial size: 85, then 170,
- // then 340, and finally 680. (The next one, 1360, is larger than 1000).
- // So, now we *start* the thumbnail operation by resizing from width 1000 to
- // width 680, which will preserve a lot of visual details such as text.
- // Then we can successively resize the image in half, 680 to 340 to 170 to 85.
- // We end up with the expected final size, but we've been doing an exact
- // divide-in-half resizing operation at the end so there is less distortion.
-
- var iterations = 0 // Number of halving operations to perform after the initial resize
- var nearestWidth = destWidth // Width closest to source width that = 2^x, x is integer
- var nearestHeight = destHeight
- while (nearestWidth < sourceWidth / 2) {
- nearestWidth *= 2
- nearestHeight *= 2
- iterations++
- }
-
- var scaled = BufferedImage(nearestWidth, nearestHeight, imageType)
-
- var g2 = scaled.createGraphics()
- setRenderingHints(g2)
- g2.drawImage(source, 0, 0, nearestWidth, nearestHeight, 0, 0, sourceWidth, sourceHeight, null)
- g2.dispose()
-
- sourceWidth = nearestWidth
- sourceHeight = nearestHeight
- source = scaled
-
- for (iteration in iterations - 1 downTo 0) {
- val halfWidth = sourceWidth / 2
- val halfHeight = sourceHeight / 2
- scaled = BufferedImage(halfWidth, halfHeight, imageType)
- g2 = scaled.createGraphics()
- setRenderingHints(g2)
- g2.drawImage(source, 0, 0, halfWidth, halfHeight, 0, 0, sourceWidth, sourceHeight, null)
- g2.dispose()
-
- sourceWidth = halfWidth
- sourceHeight = halfHeight
- source = scaled
- iterations--
- }
- return scaled
- }
- }
-
- fun getThumbnailScale(image: BufferedImage): Double {
- val maxDimension = max(image.width, image.height)
- return THUMBNAIL_SIZE / maxDimension.toDouble()
- }
-
- private fun setRenderingHints(g2: Graphics2D) {
- g2.setRenderingHint(KEY_INTERPOLATION, VALUE_INTERPOLATION_BILINEAR)
- g2.setRenderingHint(KEY_RENDERING, VALUE_RENDER_QUALITY)
- g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON)
- }
-
- /**
- * Saves the generated thumbnail image and appends the info message to an initial message
- */
- @Throws(IOException::class)
- private fun saveImageAndAppendMessage(
- image: BufferedImage,
- initialMessage: String,
- relativePath: String
- ): String {
- @Suppress("NAME_SHADOWING") var initialMessage = initialMessage
- val output = File(
- failureDir,
- getName(relativePath)
- )
- if (output.exists()) {
- val deleted = output.delete()
- assertTrue(deleted)
- }
- ImageIO.write(image, "PNG", output)
- initialMessage += "Thumbnail for current rendering stored at file://" + output.path
- // initialMessage += "\nRun the following command to accept the changes:\n";
- // initialMessage += String.format("mv %1$s %2$s", output.getPath(),
- // ImageUtils.class.getResource(relativePath).getPath());
- // The above has been commented out, since the destination path returned is in out dir
- // and it makes the tests pass without the code being actually checked in.
- return initialMessage
- }
-
- private fun getName(relativePath: String): String {
- return relativePath.substring(relativePath.lastIndexOf(separatorChar) + 1)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/MatrixMatrixMultiplicationInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/MatrixMatrixMultiplicationInterceptor.kt
deleted file mode 100644
index 41994c2d..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/MatrixMatrixMultiplicationInterceptor.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package app.cash.paparazzi.internal
-
-// Sampled from https://cs.android.com/android/platform/superproject/+/master:external/robolectric-shadows/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java;l=10-67
-object MatrixMatrixMultiplicationInterceptor {
- @Suppress("unused")
- @JvmStatic
- fun intercept(
- result: FloatArray,
- resultOffset: Int,
- lhs: FloatArray,
- lhsOffset: Int,
- rhs: FloatArray,
- rhsOffset: Int
- ) {
- require(resultOffset + 16 <= result.size) { "resultOffset + 16 > result.length" }
- require(lhsOffset + 16 <= lhs.size) { "lhsOffset + 16 > lhs.length" }
- require(rhsOffset + 16 <= rhs.size) { "rhsOffset + 16 > rhs.length" }
- for (i in 0..3) {
- val rhs_i0 = rhs[I(i, 0, rhsOffset)]
- var ri0 = lhs[I(0, 0, lhsOffset)] * rhs_i0
- var ri1 = lhs[I(0, 1, lhsOffset)] * rhs_i0
- var ri2 = lhs[I(0, 2, lhsOffset)] * rhs_i0
- var ri3 = lhs[I(0, 3, lhsOffset)] * rhs_i0
- for (j in 1..3) {
- val rhs_ij = rhs[I(i, j, rhsOffset)]
- ri0 += lhs[I(j, 0, lhsOffset)] * rhs_ij
- ri1 += lhs[I(j, 1, lhsOffset)] * rhs_ij
- ri2 += lhs[I(j, 2, lhsOffset)] * rhs_ij
- ri3 += lhs[I(j, 3, lhsOffset)] * rhs_ij
- }
- result[I(i, 0, resultOffset)] = ri0
- result[I(i, 1, resultOffset)] = ri1
- result[I(i, 2, resultOffset)] = ri2
- result[I(i, 3, resultOffset)] = ri3
- }
- }
-
- @Suppress("FunctionName")
- private fun I(i: Int, j: Int, offset: Int): Int {
- // #define I(_i, _j) ((_j)+ 4*(_i))
- return offset + j + 4 * i
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/MatrixVectorMultiplicationInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/MatrixVectorMultiplicationInterceptor.kt
deleted file mode 100644
index 403413e..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/MatrixVectorMultiplicationInterceptor.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package app.cash.paparazzi.internal
-
-// Sampled from https://cs.android.com/android/platform/superproject/+/master:external/robolectric-shadows/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java;l=69-121
-object MatrixVectorMultiplicationInterceptor {
- @Suppress("unused")
- @JvmStatic
- fun intercept(
- resultVec: FloatArray,
- resultVecOffset: Int,
- lhsMat: FloatArray,
- lhsMatOffset: Int,
- rhsVec: FloatArray,
- rhsVecOffset: Int
- ) {
- require(resultVecOffset + 4 <= resultVec.size) { "resultOffset + 4 > result.length" }
- require(lhsMatOffset + 16 <= lhsMat.size) { "lhsOffset + 16 > lhs.length" }
- require(rhsVecOffset + 4 <= rhsVec.size) { "rhsOffset + 4 > rhs.length" }
- val x = rhsVec[rhsVecOffset + 0]
- val y = rhsVec[rhsVecOffset + 1]
- val z = rhsVec[rhsVecOffset + 2]
- val w = rhsVec[rhsVecOffset + 3]
- resultVec[resultVecOffset + 0] =
- lhsMat[I(0, 0, lhsMatOffset)] * x + lhsMat[I(1, 0, lhsMatOffset)] * y +
- lhsMat[I(2, 0, lhsMatOffset)] * z + lhsMat[I(3, 0, lhsMatOffset)] * w
- resultVec[resultVecOffset + 1] =
- lhsMat[I(0, 1, lhsMatOffset)] * x + lhsMat[I(1, 1, lhsMatOffset)] * y +
- lhsMat[I(2, 1, lhsMatOffset)] * z + lhsMat[I(3, 1, lhsMatOffset)] * w
- resultVec[resultVecOffset + 2] =
- lhsMat[I(0, 2, lhsMatOffset)] * x + lhsMat[I(1, 2, lhsMatOffset)] * y +
- lhsMat[I(2, 2, lhsMatOffset)] * z + lhsMat[I(3, 2, lhsMatOffset)] * w
- resultVec[resultVecOffset + 3] =
- lhsMat[I(0, 3, lhsMatOffset)] * x + lhsMat[I(1, 3, lhsMatOffset)] * y +
- lhsMat[I(2, 3, lhsMatOffset)] * z + lhsMat[I(3, 3, lhsMatOffset)] * w
- }
-
- @Suppress("FunctionName")
- private fun I(i: Int, j: Int, offset: Int): Int {
- // #define I(_i, _j) ((_j)+ 4*(_i))
- return offset + j + 4 * i
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziAssetRepository.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziAssetRepository.kt
deleted file mode 100644
index 72bcf85..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziAssetRepository.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2017 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 app.cash.paparazzi.internal
-
-import com.android.ide.common.rendering.api.AssetRepository
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileNotFoundException
-import java.io.IOException
-import java.io.InputStream
-
-internal class PaparazziAssetRepository(private val assetPath: String) : AssetRepository() {
- @Throws(FileNotFoundException::class)
- private fun open(path: String): InputStream? {
- val asset = File(path)
- return when {
- asset.isFile -> FileInputStream(asset)
- else -> null
- }
- }
-
- override fun isSupported(): Boolean = true
-
- @Throws(IOException::class)
- override fun openAsset(
- path: String,
- mode: Int
- ): InputStream? = open("$assetPath/$path")
-
- @Throws(IOException::class)
- override fun openNonAsset(
- cookie: Int,
- path: String,
- mode: Int
- ): InputStream? = open(path)
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt
deleted file mode 100644
index 6e2b62e..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package app.cash.paparazzi.internal
-
-import app.cash.paparazzi.internal.parsers.LayoutPullParser
-import app.cash.paparazzi.internal.parsers.TagSnapshot
-import com.android.ide.common.rendering.api.ActionBarCallback
-import com.android.ide.common.rendering.api.AdapterBinding
-import com.android.ide.common.rendering.api.ILayoutPullParser
-import com.android.ide.common.rendering.api.LayoutlibCallback
-import com.android.ide.common.rendering.api.ResourceNamespace.RES_AUTO
-import com.android.ide.common.rendering.api.ResourceReference
-import com.android.ide.common.rendering.api.ResourceValue
-import com.android.ide.common.rendering.api.SessionParams.Key
-import com.android.layoutlib.bridge.android.RenderParamsFlags
-import com.android.resources.ResourceType
-import com.android.resources.ResourceType.STYLE
-import com.google.common.io.ByteStreams
-import java.io.ByteArrayInputStream
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileNotFoundException
-import java.io.IOException
-import java.lang.reflect.Modifier
-import org.kxml2.io.KXmlParser
-import org.xmlpull.v1.XmlPullParser
-import org.xmlpull.v1.XmlPullParserException
-
-internal class PaparazziCallback(
- private val logger: PaparazziLogger,
- private val resourcePackageNames: List<String>
-) : LayoutlibCallback() {
- private val projectResources = mutableMapOf<Int, ResourceReference>()
- private val resources = mutableMapOf<ResourceReference, Int>()
- private val actionBarCallback = ActionBarCallback()
- private val aaptDeclaredResources = mutableMapOf<String, TagSnapshot>()
-
- private var adaptiveIconMaskPath: String? = null
- private val loadedClasses = mutableMapOf<String, Class<*>>()
-
- @Throws(ClassNotFoundException::class)
- fun initResources() {
- for (rPackageName in resourcePackageNames) {
- val rClass = Class.forName("$rPackageName.R")
- for (resourceClass in rClass.declaredClasses) {
- val resourceType = ResourceType.fromClassName(resourceClass.simpleName) ?: continue
-
- for (field in resourceClass.declaredFields) {
- if (!Modifier.isStatic(field.modifiers)) continue
-
- // May not be final in library projects.
- val type = field.type
- try {
- if (type == Int::class.javaPrimitiveType) {
- val value = field.get(null) as Int
- val reference = ResourceReference(RES_AUTO, resourceType, field.name)
- projectResources[value] = reference
- resources[reference] = value
- } else if (type.isArray && type.componentType == Int::class.javaPrimitiveType) {
- // Ignore.
- } else {
- logger.error(null, "Unknown field type in R class: $type")
- }
- } catch (e: IllegalAccessException) {
- logger.error(e, "Malformed R class: %1\$s", "$rPackageName.R")
- }
- }
- }
- }
- }
-
- @Throws(Exception::class)
- override fun loadView(
- name: String,
- constructorSignature: Array<Class<*>>,
- constructorArgs: Array<Any>
- ): Any? {
- val viewClass = Class.forName(name)
- val viewConstructor = viewClass.getConstructor(*constructorSignature)
- viewConstructor.isAccessible = true
- return viewConstructor.newInstance(*constructorArgs)
- }
-
- override fun resolveResourceId(id: Int): ResourceReference? = projectResources[id]
-
- override fun getOrGenerateResourceId(resource: ResourceReference): Int {
- // Workaround: We load our resource map from fields in R.class, which are named using Java
- // class conventions. Therefore, we need to similarly transform style naming conventions
- // that contain periods (e.g., Widget.AppCompat.TextView) to avoid false lookup misses.
- // Long-term: Perhaps parse and load resource names from file system directly?
- val resourceKey =
- if (resource.resourceType == STYLE) resource.transformStyleResource() else resource
- return resources[resourceKey] ?: 0
- }
-
- override fun getParser(layoutResource: ResourceValue): ILayoutPullParser? {
- try {
- val value = layoutResource.value ?: return null
- if (aaptDeclaredResources.isNotEmpty() && layoutResource.resourceType == ResourceType.AAPT) {
- val aaptResource = aaptDeclaredResources.getValue(value)
- return LayoutPullParser.createFromAaptResource(aaptResource)
- }
-
- return LayoutPullParser.createFromFile(File(layoutResource.value))
- .also {
- // For parser of elements included in this parser, publish any aapt declared values
- aaptDeclaredResources.putAll(it.getAaptDeclaredAttrs())
- }
- } catch (e: FileNotFoundException) {
- return null
- }
- }
-
- override fun getAdapterItemValue(
- adapterView: ResourceReference,
- adapterCookie: Any,
- itemRef: ResourceReference,
- fullPosition: Int,
- positionPerType: Int,
- fullParentPosition: Int,
- parentPositionPerType: Int,
- viewRef: ResourceReference,
- viewAttribute: ViewAttribute,
- defaultValue: Any
- ): Any? = null
-
- override fun getAdapterBinding(
- adapterViewRef: ResourceReference,
- adapterCookie: Any,
- viewObject: Any
- ): AdapterBinding? = null
-
- override fun getActionBarCallback(): ActionBarCallback = actionBarCallback
-
- override fun createXmlParserForPsiFile(fileName: String): XmlPullParser? =
- createXmlParserForFile(fileName)
-
- override fun createXmlParserForFile(fileName: String): XmlPullParser? {
- try {
- FileInputStream(fileName).use { fileStream ->
- // Read data fully to memory to be able to close the file stream.
- val byteOutputStream = ByteArrayOutputStream()
- ByteStreams.copy(fileStream, byteOutputStream)
- val parser = KXmlParser()
- parser.setInput(ByteArrayInputStream(byteOutputStream.toByteArray()), null)
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true)
- return parser
- }
- } catch (e: IOException) {
- return null
- } catch (e: XmlPullParserException) {
- return null
- }
- }
-
- override fun createXmlParser(): XmlPullParser = KXmlParser()
-
- @Suppress("UNCHECKED_CAST")
- override fun <T> getFlag(key: Key<T>?): T? {
- return when (key) {
- RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH -> adaptiveIconMaskPath as T?
- else -> null
- }
- }
-
- fun setAdaptiveIconMaskPath(adaptiveIconMaskPath: String) {
- this.adaptiveIconMaskPath = adaptiveIconMaskPath
- }
-
- override fun findClass(name: String): Class<*> {
- val clazz = loadedClasses[name]
- logger.verbose("loadClassA($name)")
-
- try {
- if (clazz != null) {
- return clazz
- }
- val clazz2 = Class.forName(name)
- logger.verbose("loadClassB($name)")
- loadedClasses[name] = clazz2
- return clazz2
- } catch (e: LinkageError) {
- throw ClassNotFoundException("error loading class $name", e)
- } catch (e: ExceptionInInitializerError) {
- throw ClassNotFoundException("error loading class $name", e)
- } catch (e: ClassNotFoundException) {
- throw ClassNotFoundException("error loading class $name", e)
- }
- }
-
- private fun ResourceReference.transformStyleResource() =
- ResourceReference.style(namespace, name.replace('.', '_'))
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziJson.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziJson.kt
deleted file mode 100644
index 6739e81..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziJson.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal
-
-import app.cash.paparazzi.Snapshot
-import app.cash.paparazzi.TestName
-import com.squareup.moshi.FromJson
-import com.squareup.moshi.JsonAdapter
-import com.squareup.moshi.Moshi
-import com.squareup.moshi.ToJson
-import com.squareup.moshi.Types
-import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
-import java.util.Date
-
-internal object PaparazziJson {
- val moshi = Moshi.Builder()
- .add(Date::class.java, Rfc3339DateJsonAdapter())
- .add(this)
- .build()!!
-
- val listOfShotsAdapter: JsonAdapter<List<Snapshot>> =
- moshi
- .adapter<List<Snapshot>>(
- Types.newParameterizedType(List::class.java, Snapshot::class.java)
- )
- .indent(" ")
-
- val listOfStringsAdapter: JsonAdapter<List<String>> =
- moshi
- .adapter<List<String>>(
- Types.newParameterizedType(List::class.java, String::class.java)
- )
- .indent(" ")
-
- @ToJson
- fun testNameToJson(testName: TestName): String {
- return "${testName.packageName}.${testName.className}#${testName.methodName}"
- }
-
- @FromJson
- fun testNameFromJson(json: String): TestName {
- val regex = Regex("(.*)\\.([^.]*)#([^.]*)")
- val (packageName, className, methodName) = regex.matchEntire(json)!!.destructured
- return TestName(packageName, className, methodName)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziLogger.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziLogger.kt
deleted file mode 100644
index 01595f7..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziLogger.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal
-
-import app.cash.paparazzi.Paparazzi
-import com.android.ide.common.rendering.api.ILayoutLog
-import com.android.utils.ILogger
-import java.io.PrintStream
-import java.io.PrintWriter
-import java.util.logging.Level
-import java.util.logging.Logger
-import java.util.logging.Logger.getLogger
-
-/**
- * This logger delegates to java.util.Logging.
- */
-internal class PaparazziLogger : ILayoutLog, ILogger {
- private val logger: Logger = getLogger(Paparazzi::class.java.name)
- private val errors = mutableListOf<Throwable>()
-
- override fun error(
- throwable: Throwable?,
- format: String?,
- vararg args: Any
- ) {
- logger.log(Level.SEVERE, format?.format(args), throwable)
- if (throwable != null) {
- errors += throwable
- }
- }
-
- override fun warning(
- format: String,
- vararg args: Any
- ) {
- logger.log(Level.WARNING, format, args)
- }
-
- override fun info(
- format: String,
- vararg args: Any
- ) {
- logger.log(Level.INFO, format, args)
- }
-
- override fun verbose(
- format: String,
- vararg args: Any
- ) {
- logger.log(Level.FINE, format, args)
- }
-
- override fun fidelityWarning(
- tag: String?,
- message: String?,
- throwable: Throwable?,
- cookie: Any?,
- data: Any?
- ) {
- logger.log(Level.WARNING, "$tag: $message", throwable)
- }
-
- override fun error(
- tag: String?,
- message: String?,
- viewCookie: Any?,
- data: Any?
- ) {
- logger.log(Level.SEVERE, "$tag: $message")
- }
-
- override fun error(
- tag: String?,
- message: String?,
- throwable: Throwable?,
- viewCookie: Any?,
- data: Any?
- ) {
- logger.log(Level.SEVERE, "$tag: $message", throwable)
- if (throwable != null) {
- errors += throwable
- }
- }
-
- override fun warning(
- tag: String?,
- message: String?,
- viewCookie: Any?,
- data: Any?
- ) {
- logger.log(Level.WARNING, "$tag: $message")
- }
-
- override fun logAndroidFramework(priority: Int, tag: String?, message: String?) {
- logger.log(Level.INFO, "$tag [$priority]: $message")
- }
-
- fun assertNoErrors() {
- when (errors.size) {
- 0 -> return
- 1 -> throw errors[0]
- else -> throw MultipleFailuresException(errors)
- }
- }
-
- internal class MultipleFailuresException(private val causes: List<Throwable>) : Exception() {
- init {
- require(causes.isNotEmpty()) { "List of Throwables must not be empty" }
- }
-
- override val message: String
- get() = buildString {
- appendLine(String.format("There were %d errors:", causes.size))
- causes.forEach { e ->
- appendLine(String.format("%n %s: %s", e.javaClass.name, e.message))
- e.stackTrace.forEach { traceElement ->
- appendLine("\tat $traceElement")
- }
- }
- }
-
- override fun printStackTrace() {
- causes.forEach { e ->
- e.printStackTrace()
- }
- }
-
- override fun printStackTrace(s: PrintStream) {
- causes.forEach { e ->
- e.printStackTrace(s)
- }
- }
-
- override fun printStackTrace(s: PrintWriter) {
- causes.forEach { e ->
- e.printStackTrace(s)
- }
- }
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/RenderResult.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/RenderResult.kt
deleted file mode 100644
index cbf05df..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/RenderResult.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 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 app.cash.paparazzi.internal
-
-import com.android.ide.common.rendering.api.RenderSession
-import com.android.ide.common.rendering.api.Result
-import com.android.ide.common.rendering.api.ViewInfo
-import java.awt.image.BufferedImage
-
-internal data class RenderResult(
- val result: Result,
- val systemViews: List<ViewInfo>,
- val rootViews: List<ViewInfo>,
- val image: BufferedImage
-)
-
-internal fun RenderSession.toResult(): RenderResult {
- return RenderResult(result, systemRootViews.toList(), rootViews.toList(), image)
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/Renderer.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/Renderer.kt
deleted file mode 100644
index 569d1cd..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/Renderer.kt
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2016 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 app.cash.paparazzi.internal
-
-import app.cash.paparazzi.DeviceConfig
-import app.cash.paparazzi.Environment
-import app.cash.paparazzi.Flags
-import app.cash.paparazzi.internal.parsers.LayoutPullParser
-import com.android.ide.common.rendering.api.SessionParams
-import com.android.io.FolderWrapper
-import com.android.layoutlib.bridge.Bridge
-import com.android.layoutlib.bridge.android.RenderParamsFlags
-import com.android.layoutlib.bridge.impl.DelegateManager
-import java.awt.image.BufferedImage
-import java.io.Closeable
-import java.io.File
-import java.io.IOException
-import java.util.Locale
-
-/** View rendering. */
-internal class Renderer(
- private val environment: Environment,
- private val layoutlibCallback: PaparazziCallback,
- private val logger: PaparazziLogger,
- private val maxPercentDifference: Double
-) : Closeable {
- private var bridge: Bridge? = null
- private lateinit var sessionParamsBuilder: SessionParamsBuilder
-
- /** Initialize the bridge and the resource maps. */
- fun prepare(): SessionParamsBuilder {
- val platformDataResDir = File("${environment.platformDir}/data/res")
-
- @Suppress("DEPRECATION")
- val frameworkResources = com.android.ide.common.resources.deprecated.FrameworkResources(
- FolderWrapper(platformDataResDir)
- ).apply {
- loadResources()
- loadPublicResources(logger)
- }
-
- @Suppress("DEPRECATION")
- val projectResources = object : com.android.ide.common.resources.deprecated.ResourceRepository(
- FolderWrapper(environment.resDir),
- false
- ) {
- override fun createResourceItem(
- name: String
- ): com.android.ide.common.resources.deprecated.ResourceItem {
- return com.android.ide.common.resources.deprecated.ResourceItem(name)
- }
- }
- projectResources.loadResources()
-
- sessionParamsBuilder = SessionParamsBuilder(
- layoutlibCallback = layoutlibCallback,
- logger = logger,
- frameworkResources = frameworkResources,
- projectResources = projectResources,
- assetRepository = PaparazziAssetRepository(environment.assetsDir)
- )
- .plusFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true)
- .withTheme("AppTheme", true)
-
- val platformDataRoot = System.getProperty("paparazzi.platform.data.root")
- ?: throw RuntimeException("Missing system property for 'paparazzi.platform.data.root'")
- val platformDataDir = File(platformDataRoot, "data")
- val fontLocation = File(platformDataDir, "fonts")
- val nativeLibLocation = File(platformDataDir, getNativeLibDir())
- val icuLocation = File(platformDataDir, "icu" + File.separator + "icudt70l.dat")
- val buildProp = File(environment.platformDir, "build.prop")
- val attrs = File(platformDataResDir, "values" + File.separator + "attrs.xml")
- val systemProperties = DeviceConfig.loadProperties(buildProp) + mapOf(
- // We want Choreographer.USE_FRAME_TIME to be false so it uses System_Delegate.nanoTime()
- "debug.choreographer.frametime" to "false"
- )
- bridge = Bridge().apply {
- check(
- init(
- systemProperties,
- fontLocation,
- nativeLibLocation.path,
- icuLocation.path,
- DeviceConfig.getEnumMap(attrs),
- logger
- )
- ) { "Failed to init Bridge." }
- }
- Bridge.getLock()
- .lock()
- try {
- Bridge.setLog(logger)
- } finally {
- Bridge.getLock()
- .unlock()
- }
-
- return sessionParamsBuilder
- }
-
- private fun getNativeLibDir(): String {
- val osName = System.getProperty("os.name").lowercase(Locale.US)
- val osLabel = when {
- osName.startsWith("windows") -> "win"
- osName.startsWith("mac") -> {
- val osArch = System.getProperty("os.arch").lowercase(Locale.US)
- if (osArch.startsWith("x86")) "mac" else "mac-arm"
- }
- else -> "linux"
- }
- return "$osLabel/lib64"
- }
-
- override fun close() {
- bridge = null
-
- Gc.gc()
-
- dumpDelegates()
- }
-
- fun dumpDelegates() {
- if (System.getProperty(Flags.DEBUG_LINKED_OBJECTS) != null) {
- println("Objects still linked from the DelegateManager:")
- DelegateManager.dump(System.out)
- }
- }
-
- fun render(
- bridge: com.android.ide.common.rendering.api.Bridge,
- params: SessionParams,
- frameTimeNanos: Long
- ): RenderResult {
- val session = bridge.createSession(params)
-
- try {
- if (frameTimeNanos != -1L) {
- session.setElapsedFrameTimeNanos(frameTimeNanos)
- }
-
- if (!session.result.isSuccess) {
- logger.error(session.result.exception, session.result.errorMessage)
- } else {
- // Render the session with a timeout of 50s.
- val renderResult = session.render(50000)
- if (!renderResult.isSuccess) {
- logger.error(session.result.exception, session.result.errorMessage)
- }
- }
-
- return session.toResult()
- } finally {
- session.dispose()
- }
- }
-
- /** Compares the golden image with the passed image. */
- fun verify(
- goldenImageName: String,
- image: BufferedImage
- ) {
- try {
- val goldenImagePath = environment.appTestDir + "/golden/" + goldenImageName
- ImageUtils.requireSimilar(goldenImagePath, image, maxPercentDifference)
- } catch (e: IOException) {
- logger.error(e, e.message)
- }
- }
-
- /**
- * Create a new rendering session and test that rendering the given layout doesn't throw any
- * exceptions and matches the provided image.
- *
- * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
- * how far in the future is.
- */
- @JvmOverloads
- fun renderAndVerify(
- sessionParams: SessionParams,
- goldenFileName: String,
- frameTimeNanos: Long = -1
- ): RenderResult {
- val result = render(bridge!!, sessionParams, frameTimeNanos)
- verify(goldenFileName, result.image)
- return result
- }
-
- fun createParserFromPath(layoutPath: String): LayoutPullParser =
- LayoutPullParser.createFromPath("${environment.resDir}/layout/$layoutPath")
-
- /**
- * Create a new rendering session and test that rendering the given layout on given device
- * doesn't throw any exceptions and matches the provided image.
- */
- @JvmOverloads
- fun renderAndVerify(
- layoutFileName: String,
- goldenFileName: String,
- deviceConfig: DeviceConfig = DeviceConfig.NEXUS_5
- ): RenderResult {
- val sessionParams = sessionParamsBuilder
- .copy(
- layoutPullParser = createParserFromPath(layoutFileName),
- deviceConfig = deviceConfig
- )
- .build()
- return renderAndVerify(sessionParams, goldenFileName)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ResourcesInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ResourcesInterceptor.kt
deleted file mode 100644
index a7f14c8..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ResourcesInterceptor.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package app.cash.paparazzi.internal
-
-import android.content.Context
-import android.graphics.Typeface
-
-object ResourcesInterceptor {
- @JvmStatic
- fun intercept(
- context: Context,
- resId: Int
- ): Typeface? {
- return context.resources.getFont(resId)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ServiceManagerInterceptor.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ServiceManagerInterceptor.kt
deleted file mode 100644
index 4726fad..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ServiceManagerInterceptor.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package app.cash.paparazzi.internal
-
-import android.os.IBinder
-
-/**
- * The ImeTracing class attempts to initialize its [mService field in its constructor](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/util/imetracing/ImeTracing.java;l=60).
- *
- * Unfortunately, [layoutlib's version of ServiceManager](https://cs.android.com/android/platform/superproject/+/master:frameworks/layoutlib/bridge/src/android/os/ServiceManager.java;l=37)
- * throws an exception immediately.
- *
- * This interceptor overrides ServiceManager.getServiceOrThrow to simply return null instead.
- */
-object ServiceManagerInterceptor {
- @Suppress("unused")
- @JvmStatic
- fun interceptGetServiceOrThrow(@Suppress("UNUSED_PARAMETER") name: String): IBinder? = null
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/SessionParamsBuilder.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/SessionParamsBuilder.kt
deleted file mode 100644
index ea263b6..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/SessionParamsBuilder.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2017 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 app.cash.paparazzi.internal
-
-import app.cash.paparazzi.DeviceConfig
-import app.cash.paparazzi.internal.parsers.LayoutPullParser
-import com.android.SdkConstants
-import com.android.ide.common.rendering.api.AssetRepository
-import com.android.ide.common.rendering.api.ResourceNamespace
-import com.android.ide.common.rendering.api.ResourceReference
-import com.android.ide.common.rendering.api.SessionParams
-import com.android.ide.common.rendering.api.SessionParams.Key
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode
-import com.android.ide.common.resources.ResourceResolver
-import com.android.ide.common.resources.ResourceValueMap
-import com.android.layoutlib.bridge.Bridge
-import com.android.resources.LayoutDirection
-import com.android.resources.ResourceType
-
-/** Creates [SessionParams] objects. */
-internal data class SessionParamsBuilder(
- private val layoutlibCallback: PaparazziCallback,
- private val logger: PaparazziLogger,
- @Suppress("DEPRECATION")
- private val frameworkResources: com.android.ide.common.resources.deprecated.ResourceRepository,
- private val assetRepository: AssetRepository,
- @Suppress("DEPRECATION")
- private val projectResources: com.android.ide.common.resources.deprecated.ResourceRepository,
- private val deviceConfig: DeviceConfig = DeviceConfig.NEXUS_5,
- private val renderingMode: RenderingMode = RenderingMode.NORMAL,
- private val targetSdk: Int = 22,
- private val flags: Map<Key<*>, Any> = mapOf(),
- private val themeName: String? = null,
- private val isProjectTheme: Boolean = false,
- private val layoutPullParser: LayoutPullParser? = null,
- private val projectKey: Any? = null,
- private val minSdk: Int = 0,
- private val decor: Boolean = true
-) {
- fun withTheme(
- themeName: String,
- isProjectTheme: Boolean
- ): SessionParamsBuilder {
- return copy(themeName = themeName, isProjectTheme = isProjectTheme)
- }
-
- fun withTheme(themeName: String): SessionParamsBuilder {
- return when {
- themeName.startsWith(SdkConstants.PREFIX_ANDROID) -> {
- withTheme(themeName.substring(SdkConstants.PREFIX_ANDROID.length), false)
- }
- else -> withTheme(themeName, true)
- }
- }
-
- fun plusFlag(
- flag: SessionParams.Key<*>,
- value: Any
- ) = copy(flags = flags + (flag to value))
-
- fun build(): SessionParams {
- require(themeName != null)
-
- val folderConfiguration = deviceConfig.folderConfiguration
-
- @Suppress("DEPRECATION")
- val resourceResolver = ResourceResolver.create(
- mapOf<ResourceNamespace, Map<ResourceType, ResourceValueMap>>(
- ResourceNamespace.ANDROID to frameworkResources.getConfiguredResources(
- folderConfiguration
- ),
- ResourceNamespace.TODO() to projectResources.getConfiguredResources(
- folderConfiguration
- )
- ),
- ResourceReference(
- ResourceNamespace.fromBoolean(!isProjectTheme),
- ResourceType.STYLE,
- themeName
- )
- )
-
- val result = SessionParams(
- layoutPullParser, renderingMode, projectKey /* for caching */,
- deviceConfig.hardwareConfig, resourceResolver, layoutlibCallback, minSdk, targetSdk, logger
- )
- result.fontScale = deviceConfig.fontScale
-
- val localeQualifier = folderConfiguration.localeQualifier
- val layoutDirectionQualifier = folderConfiguration.layoutDirectionQualifier
- // https://cs.android.com/android-studio/platform/tools/adt/idea/+/mirror-goog-studio-main:android/src/com/android/tools/idea/rendering/RenderTask.java;l=645
- if (
- LayoutDirection.RTL == layoutDirectionQualifier.value &&
- !Bridge.isLocaleRtl(localeQualifier.tag)
- ) {
- result.locale = "ur"
- } else {
- result.locale = localeQualifier.tag
- }
- result.setRtlSupport(true)
-
- for ((key, value) in flags) {
- @Suppress("UNCHECKED_CAST")
- result.setFlag(key as Key<Any>, value)
- }
- result.setAssetRepository(assetRepository)
-
- if (!decor) {
- result.setForceNoDecor()
- }
-
- return result
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AaptAttrParser.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AaptAttrParser.kt
deleted file mode 100644
index 3c62aa8..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AaptAttrParser.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-/**
- * Copied from https://cs.android.com/android-studio/platform/tools/adt/idea/+/858f81bb7c350bc7a05daad36edefd21f74c8cef:android/src/com/android/tools/idea/rendering/parsers/AaptAttrParser.java
- *
- * Interface for parsers that support declaration of inlined {@code aapt:attr} attributes
- */
-interface AaptAttrParser {
- /**
- * Returns a [Map] that contains all the `aapt:attr` elements declared in this or any
- * children parsers. This list can be used to resolve `@aapt/_aapt` references into this parser.
- */
- fun getAaptDeclaredAttrs(): Map<String, TagSnapshot>
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AaptAttrSnapshot.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AaptAttrSnapshot.kt
deleted file mode 100644
index 4105eee..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AaptAttrSnapshot.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-import com.android.SdkConstants.AAPT_ATTR_PREFIX
-import com.android.SdkConstants.AAPT_PREFIX
-
-/**
- * Derived from https://cs.android.com/android-studio/platform/tools/adt/idea/+/mirror-goog-studio-master-dev:android/src/com/android/tools/idea/rendering/parsers/AaptAttrAttributeSnapshot.java
- *
- * Aapt attributes are attributes that instead of containing a reference, contain the inlined value
- * of the reference. This snapshot will generate a dynamic reference that will be used by the
- * resource resolution to be able to retrieve the inlined value.
- */
-class AaptAttrSnapshot(
- override val namespace: String,
- override val prefix: String,
- override val name: String,
- val id: String,
- val bundledTag: TagSnapshot
-) : AttributeSnapshot(namespace, prefix, name, "${AAPT_ATTR_PREFIX}$AAPT_PREFIX$id")
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AttributeSnapshot.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AttributeSnapshot.kt
deleted file mode 100644
index 50b658c..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/AttributeSnapshot.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-/**
- * Derived from https://cs.android.com/android-studio/platform/tools/adt/idea/+/mirror-goog-studio-master-dev:android/src/com/android/tools/idea/rendering/parsers/AttributeSnapshot.java
- *
- * A snapshot of an attribute value pulled from an XML resource.
- * Used in conjunction with [TagSnapshot].
- */
-open class AttributeSnapshot(
- open val namespace: String,
- open val prefix: String?,
- open val name: String,
- open val value: String
-) {
- override fun toString() = "$name: $value"
-
- // since data classes can't be subclassed
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (javaClass != other?.javaClass) return false
-
- other as AttributeSnapshot
-
- if (namespace != other.namespace) return false
- if (prefix != other.prefix) return false
- if (name != other.name) return false
- if (value != other.value) return false
-
- return true
- }
-
- override fun hashCode(): Int {
- var result = namespace.hashCode()
- result = 31 * result + prefix.hashCode()
- result = 31 * result + name.hashCode()
- result = 31 * result + value.hashCode()
- return result
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/InMemoryParser.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/InMemoryParser.kt
deleted file mode 100644
index 5b709fb..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/InMemoryParser.kt
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-import org.kxml2.io.KXmlParser
-import org.xmlpull.v1.XmlPullParserException
-
-/**
- * Derived from https://cs.android.com/android-studio/platform/tools/adt/idea/+/858f81bb7c350bc7a05daad36edefd21f74c8cef:android/src/com/android/tools/idea/rendering/parsers/LayoutPullParser.java;bpv=0;bpt=0
- *
- * A parser implementation that walks an in-memory XML DOM tree.
- */
-abstract class InMemoryParser : KXmlParser() {
- abstract fun rootTag(): TagSnapshot
-
- private val nodeStack = mutableListOf<TagSnapshot>()
- private var parsingState = START_DOCUMENT
-
- override fun getAttributeCount(): Int {
- val tag = getCurrentNode() ?: return 0
- return tag.attributes.size
- }
-
- override fun getAttributeName(i: Int): String? {
- val attribute = getAttribute(i) ?: return null
- return attribute.name
- }
-
- override fun getAttributeNamespace(i: Int): String {
- val attribute = getAttribute(i) ?: return ""
- return attribute.namespace
- }
-
- override fun getAttributePrefix(i: Int): String? {
- val attribute = getAttribute(i) ?: return null
- return attribute.prefix
- }
-
- override fun getAttributeValue(i: Int): String? {
- val attribute = getAttribute(i) ?: return null
- return attribute.value
- }
-
- override fun getAttributeValue(
- namespace: String?,
- name: String?
- ): String? {
- val tag = getCurrentNode() ?: return null
- return tag.attributes.find { it.name == name }?.value
- }
-
- override fun getDepth(): Int = nodeStack.size
-
- override fun getName(): String? {
- if (parsingState == START_TAG || parsingState == END_TAG) {
- // Should only be called when START_TAG
- val currentNode = getCurrentNode()!!
- return currentNode.name
- }
- return null
- }
-
- @Throws(XmlPullParserException::class)
- override fun next(): Int {
- when (parsingState) {
- END_DOCUMENT -> throw XmlPullParserException("Nothing after the end")
- START_DOCUMENT -> onNextFromStartDocument()
- START_TAG -> onNextFromStartTag()
- END_TAG -> onNextFromEndTag()
- }
- return parsingState
- }
-
- private fun getCurrentNode(): TagSnapshot? = nodeStack.lastOrNull()
-
- private fun getAttribute(i: Int): AttributeSnapshot? {
- if (parsingState != START_TAG) {
- throw IndexOutOfBoundsException()
- }
- val tag = getCurrentNode() ?: return null
- return tag.attributes[i]
- }
-
- private fun push(node: TagSnapshot) {
- nodeStack.add(node)
- }
-
- private fun pop(): TagSnapshot = nodeStack.removeLast()
-
- private fun onNextFromStartDocument() {
- val rootTag = rootTag()
- @Suppress("SENSELESS_COMPARISON")
- parsingState = if (rootTag != null) {
- push(rootTag)
- START_TAG
- } else {
- END_DOCUMENT
- }
- }
-
- private fun onNextFromStartTag() {
- // get the current node, and look for text or children (children first)
- // Should only be called when START_TAG
- val node = getCurrentNode()!!
- val children = node.children
- parsingState = if (children.isNotEmpty()) {
- // move to the new child, and don't change the state.
- push(children[0])
-
- // in case the current state is CURRENT_DOC, we set the proper state.
- START_TAG
- } else {
- if (parsingState == START_DOCUMENT) {
- // this handles the case where there's no node.
- END_DOCUMENT
- } else {
- END_TAG
- }
- }
- }
-
- private fun onNextFromEndTag() {
- // look for a sibling. if no sibling, go back to the parent
- // Should only be called when END_TAG
- var node = getCurrentNode()!!
- val sibling = node.next
- if (sibling != null) {
- node = sibling
- // to go to the sibling, we need to remove the current node,
- pop()
- // and add its sibling.
- push(node)
- parsingState = START_TAG
- } else {
- // move back to the parent
- pop()
-
- // we have only one element left (myRoot), then we're done with the document.
- parsingState = if (nodeStack.isEmpty()) {
- END_DOCUMENT
- } else {
- END_TAG
- }
- }
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt
deleted file mode 100644
index 8f1a94a..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package app.cash.paparazzi.internal.parsers
-
-import com.android.SdkConstants.ATTR_IGNORE
-import com.android.SdkConstants.EXPANDABLE_LIST_VIEW
-import com.android.SdkConstants.GRID_VIEW
-import com.android.SdkConstants.LIST_VIEW
-import com.android.SdkConstants.SPINNER
-import com.android.SdkConstants.TOOLS_URI
-import com.android.ide.common.rendering.api.ILayoutPullParser
-import com.android.ide.common.rendering.api.ResourceNamespace
-import java.io.ByteArrayInputStream
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileNotFoundException
-import java.io.IOError
-import java.io.InputStream
-import java.nio.charset.Charset
-import okio.buffer
-import okio.source
-import org.xmlpull.v1.XmlPullParserException
-
-/**
- * A layout parser that holds an in-memory tree of a given resource for subsequent traversal
- * during the inflation process
- */
-internal class LayoutPullParser : InMemoryParser, AaptAttrParser, ILayoutPullParser {
- private constructor(inputStream: InputStream) : super() {
- try {
- val buffer = inputStream.source().buffer()
-
- setFeature(FEATURE_PROCESS_NAMESPACES, true)
- setInput(buffer.peek().inputStream(), null)
-
- // IntelliJ uses XmlFile/PsiFile to parse tag snapshots,
- // leaving XmlPullParser for Android to parse resources as usual
- // Here, we use the same XmlPullParser approach for both, which means
- // we need reinitialize the document stream between the two passes.
- val resourceParser = ResourceParser(buffer.inputStream())
- root = resourceParser.createTagSnapshot()
-
- // Obtain a list of all the aapt declared attributes
- declaredAaptAttrs = findDeclaredAaptAttrs(root)
- } catch (e: XmlPullParserException) {
- throw IOError(e)
- }
- }
-
- private constructor(aaptResource: TagSnapshot) : super() {
- root = aaptResource
- declaredAaptAttrs = emptyMap()
- }
-
- private val root: TagSnapshot
- private val declaredAaptAttrs: Map<String, TagSnapshot>
-
- private var layoutNamespace = ResourceNamespace.RES_AUTO
-
- override fun rootTag() = root
-
- @Suppress("SENSELESS_COMPARISON")
- override fun getViewCookie(): Any? {
- // TODO: Implement this properly.
- val name = super.getName() ?: return null
-
- // Store tools attributes if this looks like a layout we'll need adapter view
- // bindings for in the LayoutlibCallback.
- if (LIST_VIEW == name || EXPANDABLE_LIST_VIEW == name || GRID_VIEW == name || SPINNER == name) {
- var map: MutableMap<String, String>? = null
- val count = attributeCount
- for (i in 0 until count) {
- val namespace = getAttributeNamespace(i)
- if (namespace != null && namespace == TOOLS_URI) {
- val attribute = getAttributeName(i)!!
- if (attribute == ATTR_IGNORE) {
- continue
- }
- if (map == null) {
- map = HashMap(4)
- }
- map[attribute] = getAttributeValue(i)!!
- }
- }
-
- return map
- }
-
- return null
- }
-
- override fun getLayoutNamespace(): ResourceNamespace = layoutNamespace
-
- override fun getAaptDeclaredAttrs(): Map<String, TagSnapshot> = declaredAaptAttrs
-
- fun setLayoutNamespace(layoutNamespace: ResourceNamespace) {
- this.layoutNamespace = layoutNamespace
- }
-
- private fun findDeclaredAaptAttrs(tag: TagSnapshot): Map<String, TagSnapshot> {
- if (!tag.hasDeclaredAaptAttrs) {
- // Nor tag or any of the children has any aapt:attr declarations, we can stop here.
- return emptyMap()
- }
-
- return buildMap {
- tag.attributes
- .filterIsInstance<AaptAttrSnapshot>()
- .forEach { attr ->
- val bundledTag = attr.bundledTag
- put(attr.id, bundledTag)
- for (child in bundledTag.children) {
- putAll(findDeclaredAaptAttrs(child))
- }
- }
- for (child in tag.children) {
- putAll(findDeclaredAaptAttrs(child))
- }
- }
- }
-
- companion object {
- @Throws(FileNotFoundException::class)
- fun createFromFile(layoutFile: File) = LayoutPullParser(FileInputStream(layoutFile))
-
- /**
- * @param layoutPath Must start with '/' and be relative to test resources.
- */
- fun createFromPath(layoutPath: String): LayoutPullParser {
- @Suppress("NAME_SHADOWING") var layoutPath = layoutPath
- if (layoutPath.startsWith("/")) {
- layoutPath = layoutPath.substring(1)
- }
-
- return LayoutPullParser(
- LayoutPullParser::class.java.classLoader!!.getResourceAsStream(layoutPath)
- )
- }
-
- fun createFromString(contents: String): LayoutPullParser {
- return LayoutPullParser(
- ByteArrayInputStream(contents.toByteArray(Charset.forName("UTF-8")))
- )
- }
-
- fun createFromAaptResource(aaptResource: TagSnapshot): LayoutPullParser {
- return LayoutPullParser(aaptResource)
- }
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt
deleted file mode 100644
index f90475b..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-import com.android.SdkConstants.AAPT_URI
-import com.android.SdkConstants.TAG_ATTR
-import java.io.InputStream
-import org.kxml2.io.KXmlParser
-
-/**
- * An XML resource parser that creates a tree of [TagSnapshot]s
- */
-class ResourceParser(inputStream: InputStream) : KXmlParser() {
- init {
- setFeature(FEATURE_PROCESS_NAMESPACES, true)
- setInput(inputStream, null)
-
- require(START_DOCUMENT, null, null)
- next()
- }
-
- fun createTagSnapshot(): TagSnapshot {
- require(START_TAG, null, null)
-
- // need to store now, since TagSnapshot is created on end tag after parser mark has moved
- val tagName = name
- val tagNamespace = namespace
- val prefix = prefix
-
- val attributes = createAttributesForTag()
-
- var hasDeclaredAaptAttrs = false
- var last: TagSnapshot? = null
- val children = mutableListOf<TagSnapshot>()
- while (eventType != END_DOCUMENT) {
- when (next()) {
- START_TAG -> {
- if (AAPT_URI == namespace) {
- if (TAG_ATTR == name) {
- val attrAttribute = createAttrTagSnapshot()
- if (attrAttribute != null) {
- attributes += attrAttribute
- hasDeclaredAaptAttrs = true
- }
- }
- // Since we save the aapt:attr tags as an attribute, we do not save them as a child element. Skip.
- } else {
- val child = createTagSnapshot()
- hasDeclaredAaptAttrs = hasDeclaredAaptAttrs || child.hasDeclaredAaptAttrs
- children += child
- if (last != null) {
- last.next = child
- }
- last = child
- }
- }
- END_TAG -> {
- return TagSnapshot(
- tagName,
- tagNamespace,
- prefix,
- attributes,
- children.toList(),
- hasDeclaredAaptAttrs
- )
- }
- }
- }
-
- throw IllegalStateException("We should never reach here")
- }
-
- private fun createAttrTagSnapshot(): AaptAttrSnapshot? {
- require(START_TAG, null, "attr")
-
- val name = getAttributeValue(null, "name") ?: return null
- val prefix = findPrefixByQualifiedName(name)
- val namespace = getNamespace(prefix)
- val localName = findLocalNameByQualifiedName(name)
- val id = (++uniqueId).toString()
-
- var bundleTagSnapshot: TagSnapshot? = null
- loop@ while (eventType != END_TAG) {
- when (nextTag()) {
- START_TAG -> {
- bundleTagSnapshot = createTagSnapshot()
- }
- END_TAG -> {
- break@loop
- }
- }
- }
-
- return if (bundleTagSnapshot != null) {
- // swallow end tag
- nextTag()
- require(END_TAG, null, "attr")
-
- AaptAttrSnapshot(namespace, prefix, localName, id, bundleTagSnapshot)
- } else {
- null
- }
- }
-
- private fun findPrefixByQualifiedName(name: String): String {
- val prefixEnd = name.indexOf(':')
- return if (prefixEnd > 0) {
- name.substring(0, prefixEnd)
- } else ""
- }
-
- private fun findLocalNameByQualifiedName(name: String): String {
- return name.substring(name.indexOf(':') + 1)
- }
-
- private fun createAttributesForTag(): MutableList<AttributeSnapshot> {
- return buildList {
- for (i in 0 until attributeCount) {
- add(
- AttributeSnapshot(
- getAttributeNamespace(i),
- getAttributePrefix(i),
- getAttributeName(i),
- getAttributeValue(i)
- )
- )
- }
- }.toMutableList()
- }
-
- companion object {
- private var uniqueId = 0L
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/TagSnapshot.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/TagSnapshot.kt
deleted file mode 100644
index 19cab20..0000000
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/TagSnapshot.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-/**
- * Derived from https://cs.android.com/android-studio/platform/tools/adt/idea/+/mirror-goog-studio-master-dev:android/src/com/android/tools/idea/rendering/parsers/TagSnapshot.java
- *
- * A snapshot of the state of an xml tag.
- *
- * Used by the rendering architecture to be able to hold a consistent view of
- * the layout files across a long rendering operation without holding read locks,
- * as well as to for example let the property sheet evaluate and paint the values
- * of properties as they were at the time of rendering, not as they are at the current
- * instant.
- */
-data class TagSnapshot(
- val name: String,
- val namespace: String,
- val prefix: String?,
- val attributes: List<AttributeSnapshot>,
- val children: List<TagSnapshot>,
- val hasDeclaredAaptAttrs: Boolean = false
-) {
- var next: TagSnapshot? = null
-
- @Suppress("unused") // Used for debugging
- fun printFormatted(): String {
- indent++
- val output = """
- |$name:
- |${pad(indent + 1)}attributes: ${print(attributes)}
- |${pad(indent + 1)}children: ${print(children)}
- """.trimMargin()
- indent--
- return output
- }
-
- private fun print(children: List<*>): String {
- if (children.isEmpty()) return children.toString()
-
- indent++
- val output = children.joinToString(
- prefix = "[\n${pad(indent + 1)}",
- separator = "\n${pad(indent + 1)}",
- postfix = "\n${pad(indent)}]"
- )
- indent--
- return output
- }
-
- private fun pad(length: Int): String = " ".repeat(length)
-
- companion object {
- var indent = -1
- }
-}
diff --git a/external/paparazzi/paparazzi/src/main/resources/index.html b/external/paparazzi/paparazzi/src/main/resources/index.html
deleted file mode 100644
index 327f8b0..0000000
--- a/external/paparazzi/paparazzi/src/main/resources/index.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <style type="text/css">
- body {
- background: #212121;
- text-align: center;
- }
-
- .screen {
- margin: 0.2em;
- display: inline-block;
- position: relative;
- overflow: hidden;
- }
-
- .screen img, .screen video {
- width: 300px;
- }
-
- div.overlay__hovered {
- display: block;
- }
-
- .overlay {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- background: rgba(25, 0, 237, .68);
- color: #fff;
- opacity: 0;
- display: none;
- transition: 150ms;
-
- -webkit-animation-name: slideIn;
- -webkit-animation-duration: 0.4s;
- animation-name: slideIn;
- animation-duration: 0.4s;
- animation-fill-mode: forwards;
- }
-
- @-webkit-keyframes slideIn {
- from {bottom: -300px; opacity: 0}
- to {bottom: 0; opacity: 1}
- }
-
- @keyframes slideIn {
- from {bottom: -300px; opacity: 0}
- to {bottom: 0; opacity: 1}
- }
-
- .test__details {
- text-align: left;
- padding-left: 1em;
- }
-
- .test__details__name,
- .test__details__class,
- .test__details__package {
- line-height: 0.7em;
- }
-
- .test__details__timestamp {
- margin-top: 2em;
- }
-
- .test__details__selector {
- width: 16px;
- height: 16px;
- border-radius: 50%;
- display: inline-block;
- border: 2px solid #fff;
- margin: .1em;
- margin-bottom: 1.3em;
- margin-top: 1em;
- }
-
- .test__details__selector:hover {
- background-color: white;
- }
- </style>
-</head>
-
-<script src="index.js"></script>
-<script src="paparazzi.js"></script>
-
-<body onload="bootstrap()">
- <span id="rootContainer"/>
-</body>
-</html>
diff --git a/external/paparazzi/paparazzi/src/main/resources/paparazzi.js b/external/paparazzi/paparazzi/src/main/resources/paparazzi.js
deleted file mode 100644
index 5c12ab1..0000000
--- a/external/paparazzi/paparazzi/src/main/resources/paparazzi.js
+++ /dev/null
@@ -1,222 +0,0 @@
-window.runs = {};
-
-class Run {
- constructor(id, data) {
- this.id = id;
- // TODO(oldergod) which entries are required/optional?
- this.data = data;
- }
-}
-
-class Shot {
- constructor(name, test) {
- this.name = name;
- this.test = test;
-
- [, this.package, this.clazz, this.method] = Shot.TestMethodRegex.exec(test);
-
- this.runs = [];
- }
-
- static get TestMethodRegex() {
- return /^(.*)\.(.*)#(.*)$/;
- }
-
- addRun(runId, file, timestamp) {
- this.runs.push(
- {
- 'id': runId,
- 'file': file,
- 'timestamp': timestamp
- }
- );
-
- if (file.endsWith('.png')) {
- this.img.src = file;
- this.img.style.display = 'inline';
- this.video.style.display = 'none';
- } else {
- this.video.src = file;
- this.video.style.display = 'inline';
- this.img.style.display = 'none';
- }
- this.timestampP.innerText = timestamp;
-
- const circle = document.createElement('div');
- circle.classList.add('test__details__selector', `run-${runId}`);
- circle.onmouseover = function (e) {
- if (file.endsWith('.png')) {
- this.img.src = file;
- } else {
- this.video.src = file;
- }
-
- for (let shot of Object.values(paparazziRenderer.shots)) {
- let found = false;
- for (let run of shot.runs) {
- if (runId == run.id) {
- shot.img.src = run.file;
- shot.timestampP.innerText = run.timestamp;
-
- found = true;
- break;
- }
- }
- shot.img.style.opacity = found ? "1" : "0.3";
- }
- }.bind(this);
- this.overlayDiv.appendChild(circle);
- }
-
- removeRun(runId) {
- const index = this.runs.indexOf((run) => run.id == runId);
- if (index == -1) return;
-
- this.runs.splice(index, 1);
- }
-
- inflate() {
- const screenDiv = document.createElement('div');
- screenDiv.classList.add('screen');
-
- document.rootContainer.appendChild(screenDiv);
-
- const img = document.createElement('img');
- const video = document.createElement('video');
- video.autoplay = 'autoplay';
- video.muted = 'muted';
- video.loop = 'loop';
-
- const overlayDiv = document.createElement('div');
- overlayDiv.classList.add('overlay');
-
- screenDiv.appendChild(img);
- screenDiv.appendChild(video);
- screenDiv.appendChild(overlayDiv);
- screenDiv.onmouseover = function (e) {
- overlayDiv.classList.add('overlay__hovered');
- }.bind(this);
- screenDiv.onmouseout = function (e) {
- overlayDiv.classList.remove('overlay__hovered');
- }.bind(this);
-
- const nameP = document.createElement('p');
- nameP.classList.add('test__details', 'test__details__name');
-
- const classP = document.createElement('p');
- classP.classList.add('test__details', 'test__details__class');
-
- const packageP = document.createElement('p');
- packageP.classList.add('test__details', 'test__details__package');
-
- const timestampP = document.createElement('p');
- timestampP.classList.add('test__details', 'test__details__timestamp');
-
- overlayDiv.appendChild(nameP);
- overlayDiv.appendChild(classP);
- overlayDiv.appendChild(packageP);
- overlayDiv.appendChild(timestampP);
-
- nameP.innerText = this.method;
- if (this.name !== undefined) {
- nameP.innerText += ` ${this.name}`;
- }
- classP.innerText = this.clazz;
- packageP.innerText = this.package;
-
- // hold references to the DOM for later updates
- this.img = img;
- this.video = video;
- this.timestampP = timestampP;
- this.overlayDiv = overlayDiv;
- }
-}
-
-class PaparazziRenderer {
- constructor() {
- // Used for content comparison for we only re-render the updated ones.
- this.currentRuns = {};
- // Used to store runs we know won't be updated anymore.
- this.lockedRunIds = [];
- this.shots = {}; // Key is `${test}${name}`, Value is a Shot.
- }
-
- start() {
- this.loadRunScript('index.js');
- for (let runId of window.all_runs) {
- this.loadRunScript(`runs/${runId}.js`);
- }
- setInterval(this.refresh.bind(this), 100);
- }
-
- render(run) {
- if (this.currentRuns[run.id]
- && JSON.stringify(this.currentRuns[run.id]) == JSON.stringify(run)) {
- // This run didn't change.
- return;
- }
- this.currentRuns[run.id] = run;
- console.log('rendering', run);
-
- for (let datum of run.data) {
- const key = `${datum.testName}${datum.name}`;
- let shot = this.shots[key];
- if (!shot) {
- console.log('New shot detected', shot);
- shot = new Shot(datum.name, datum.testName);
- this.shots[key] = shot;
- shot.inflate();
- } else {
- //shot.removeRun(run.id);
- }
-
- console.log('Adding run to shot', shot);
- shot.addRun(run.id, datum.file, datum.timestamp);
-
- // TODO setup listeners for filters/hovering, etc
- }
- }
-
- renderAll() {
- this.loadRunScript('index.js');
- for (let runId of window.all_runs) {
- if (this.lockedRunIds.includes(runId)) {
- continue;
- }
- // The js loading is async so the rendering can happen in the next refresh
- this.loadRunScript(`runs/${runId}.js`);
-
- this.render(new Run(runId, window.runs[runId]));
-
- const lastRunId = window.all_runs[window.all_runs.length - 1];
- if (runId != lastRunId) {
- // This run isn't the last run so we know it ain't gonna be updated.
- this.lockedRunIds.push(runId);
- delete this.currentRuns[runId];
- }
- }
- }
-
- refresh() {
- if (window.all_runs.length == 0) return;
-
- this.renderAll();
- }
-
- loadRunScript(js) {
- const script = document.createElement('script');
- script.src = js;
- script.onload = function () {
- this.remove();
- }
- document.head.appendChild(script);
- }
-}
-
-const paparazziRenderer = new PaparazziRenderer();
-console.log(paparazziRenderer);
-
-function bootstrap() {
- document.rootContainer = document.getElementById('rootContainer');
- paparazziRenderer.start();
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
deleted file mode 100644
index 80979c7..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import java.awt.image.BufferedImage
-import java.io.File
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.attribute.BasicFileAttributes
-import java.nio.file.attribute.FileTime
-import java.time.Instant
-import java.util.Date
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TemporaryFolder
-
-class HtmlReportWriterTest {
- @get:Rule
- val reportRoot: TemporaryFolder = TemporaryFolder()
-
- @get:Rule
- val snapshotRoot: TemporaryFolder = TemporaryFolder()
-
- private val anyImage = BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)
- private val anyImageHash = "9069ca78e7450a285173431b3e52c5c25299e473"
-
- @Test
- fun happyPath() {
- val htmlReportWriter = HtmlReportWriter("run_one", reportRoot.root)
- htmlReportWriter.use {
- val frameHandler = htmlReportWriter.newFrameHandler(
- Snapshot(
- name = "loading",
- testName = TestName("app.cash.paparazzi", "CelebrityTest", "testSettings"),
- timestamp = Instant.parse("2019-03-20T10:27:43Z").toDate(),
- tags = listOf("redesign")
- ),
- 1,
- -1
- )
- frameHandler.use {
- frameHandler.handle(anyImage)
- }
- }
-
- assertThat(File("${reportRoot.root}/index.js")).hasContent(
- """
- |window.all_runs = [
- | "run_one"
- |];
- |
- """.trimMargin()
- )
-
- assertThat(File("${reportRoot.root}/runs/run_one.js")).hasContent(
- """
- |window.runs["run_one"] = [
- | {
- | "name": "loading",
- | "testName": "app.cash.paparazzi.CelebrityTest#testSettings",
- | "timestamp": "2019-03-20T10:27:43.000Z",
- | "tags": [
- | "redesign"
- | ],
- | "file": "images/$anyImageHash.png"
- | }
- |];
- |
- """.trimMargin()
- )
- }
-
- @Test
- fun sanitizeForFilename() {
- assertThat("0 Dollars".sanitizeForFilename()).isEqualTo("0_dollars")
- assertThat("`!#$%&*+=|\\'\"<>?/".sanitizeForFilename()).isEqualTo("_________________")
- assertThat("~@^()[]{}:;,.".sanitizeForFilename()).isEqualTo("~@^()[]{}:;,.")
- }
-
- @Test
- fun noSnapshotOnFailure() {
- val htmlReportWriter = HtmlReportWriter("run_one", reportRoot.root)
- htmlReportWriter.use {
- val frameHandler = htmlReportWriter.newFrameHandler(
- snapshot = Snapshot(
- name = "loading",
- testName = TestName("app.cash.paparazzi", "CelebrityTest", "testSettings"),
- timestamp = Instant.parse("2019-03-20T10:27:43Z").toDate()
- ),
- frameCount = 4,
- fps = -1
- )
- frameHandler.use {
- // intentionally empty, to simulate no content written on exception
- }
- }
-
- assertThat(File(reportRoot.root, "images")).isEmptyDirectory
- assertThat(File(reportRoot.root, "videos")).isEmptyDirectory
- }
-
- @Test
- fun alwaysOverwriteOnRecord() {
- // set record mode
- System.setProperty("paparazzi.test.record", "true")
-
- val htmlReportWriter = HtmlReportWriter("record_run", reportRoot.root, snapshotRoot.root)
- htmlReportWriter.use {
- val now = Instant.parse("2021-02-23T10:27:43Z")
- val snapshot = Snapshot(
- name = "test",
- testName = TestName("app.cash.paparazzi", "HomeView", "testSettings"),
- timestamp = now.toDate()
- )
- val file =
- File("${snapshotRoot.root}/images/app.cash.paparazzi_HomeView_testSettings_test.png")
- val golden = file.toPath()
-
- // precondition
- assertThat(golden).doesNotExist()
-
- // take 1
- val frameHandler1 = htmlReportWriter.newFrameHandler(
- snapshot = snapshot,
- frameCount = 1,
- fps = -1
- )
- frameHandler1.use { frameHandler1.handle(anyImage) }
- assertThat(golden).exists()
- val timeFirstWrite = golden.lastModifiedTime()
-
- // I know....but guarantees writes won't happen in same tick
- Thread.sleep(100)
-
- // take 2
- val frameHandler2 = htmlReportWriter.newFrameHandler(
- snapshot = snapshot.copy(timestamp = now.plusSeconds(1).toDate()),
- frameCount = 1,
- fps = -1
- )
- frameHandler2.use { frameHandler2.handle(anyImage) }
- assertThat(golden).exists()
- val timeOverwrite = golden.lastModifiedTime()
-
- // should always overwrite
- assertThat(timeOverwrite).isGreaterThan(timeFirstWrite)
- }
- }
-
- private fun Instant.toDate() = Date(toEpochMilli())
-
- private fun Path.lastModifiedTime(): FileTime {
- return Files.readAttributes(this, BasicFileAttributes::class.java).lastModifiedTime()
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt
deleted file mode 100644
index 356a6c8..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-import android.animation.AnimationHandler
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import android.graphics.Canvas
-import android.graphics.Color
-import android.view.Choreographer
-import android.view.Choreographer.CALLBACK_ANIMATION
-import android.view.View
-import android.view.animation.LinearInterpolator
-import android.widget.Button
-import com.android.internal.lang.System_Delegate
-import java.util.concurrent.TimeUnit
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-
-class PaparazziTest {
- @get:Rule
- val paparazzi = Paparazzi()
-
- @Ignore("b/245941625")
- @Test
- fun drawCalls() {
- val log = mutableListOf<String>()
-
- val view = object : View(paparazzi.context) {
- override fun onDraw(canvas: Canvas) {
- log += "onDraw time=$time"
- }
- }
-
- paparazzi.snapshot(view)
-
- assertThat(log).containsExactly("onDraw time=0")
- }
-
- @Ignore("b/245941625")
- @Test
- fun resetsAnimationHandler() {
- assertThat(AnimationHandler.sAnimatorHandler.get()).isNull()
-
- // Why Button? Because it sets a StateListAnimator on window attach
- // See https://github.com/cashapp/paparazzi/pull/319
- paparazzi.snapshot(Button(paparazzi.context))
-
- assertThat(AnimationHandler.sAnimatorHandler.get()).isNull()
- }
-
- @Ignore("b/245941625")
- @Test
- fun animationEvents() {
- val log = mutableListOf<String>()
-
- val animator = ValueAnimator.ofFloat(0.0f, 1.0f)
- animator.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationStart(animation: Animator) {
- log += "onAnimationStart time=$time animationElapsed=${animator.animatedValue}"
- }
-
- override fun onAnimationEnd(animation: Animator) {
- log += "onAnimationEnd time=$time animationElapsed=${animator.animatedValue}"
- }
- })
-
- val view = object : View(paparazzi.context) {
- override fun onDraw(canvas: Canvas) {
- log += "onDraw time=$time animationElapsed=${animator.animatedValue}"
- }
- }
-
- animator.addUpdateListener {
- log += "onAnimationUpdate time=$time animationElapsed=${animator.animatedValue}"
-
- val colorComponent = it.animatedFraction
- view.setBackgroundColor(Color.argb(1f, colorComponent, colorComponent, colorComponent))
- }
-
- animator.startDelay = 2_000L
- animator.duration = 1_000L
- animator.interpolator = LinearInterpolator()
- animator.start()
-
- paparazzi.gif(view, start = 1_000L, end = 4_000L, fps = 4)
-
- assertThat(log).containsExactly(
- "onDraw time=1000 animationElapsed=0.0",
- "onAnimationStart time=2000 animationElapsed=0.0",
- "onAnimationUpdate time=2000 animationElapsed=0.0",
- "onDraw time=2000 animationElapsed=0.0",
- "onAnimationUpdate time=2250 animationElapsed=0.25",
- "onDraw time=2250 animationElapsed=0.25",
- "onAnimationUpdate time=2500 animationElapsed=0.5",
- "onDraw time=2500 animationElapsed=0.5",
- "onAnimationUpdate time=2750 animationElapsed=0.75",
- "onDraw time=2750 animationElapsed=0.75",
- "onAnimationUpdate time=3000 animationElapsed=1.0",
- "onAnimationEnd time=3000 animationElapsed=1.0",
- "onDraw time=3000 animationElapsed=1.0"
- )
- }
-
- @Test
- @Ignore
- fun frameCallbacksExecutedAfterLayout() {
- val log = mutableListOf<String>()
-
- val view = object : View(paparazzi.context) {
- override fun onAttachedToWindow() {
- super.onAttachedToWindow()
- Choreographer.getInstance()
- .postCallback(
- CALLBACK_ANIMATION,
- { log += "view width=$width height=$height" },
- false
- )
- }
- }
-
- paparazzi.snapshot(view)
-
- assertThat(log).containsExactly("view width=1080 height=1776")
- }
-
- @Ignore("b/245941625")
- @Test
- fun throwsRenderingExceptions() {
- val view = object : View(paparazzi.context) {
- override fun onAttachedToWindow() {
- throw Throwable("Oops")
- }
- }
-
- val thrown = try {
- paparazzi.snapshot(view)
- false
- } catch (exception: Throwable) {
- true
- }
-
- assertThat(thrown).isTrue
- }
-
- private val time: Long
- get() {
- return TimeUnit.NANOSECONDS.toMillis(System_Delegate.nanoTime() - Paparazzi.TIME_OFFSET_NANOS)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/R.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/R.kt
deleted file mode 100644
index 5827e33..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/R.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi
-
-/** Simulate an empty R.java for this package. */
-class R
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt
deleted file mode 100644
index d774099..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-package app.cash.paparazzi
-
-import android.content.Context
-import android.graphics.Color
-import android.graphics.drawable.GradientDrawable
-import android.view.Gravity
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.LinearLayout
-import android.widget.TextView
-import app.cash.paparazzi.internal.ImageUtils
-import com.android.ide.common.rendering.api.SessionParams
-import java.awt.image.BufferedImage
-import java.io.File
-import javax.imageio.ImageIO
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.Description
-
-class RenderingModeTest {
-
- @Ignore("b/245941625")
- @Test
- fun `shrinks to wrap view`() {
- Paparazzi(
- snapshotHandler = TestSnapshotVerifier(),
- deviceConfig = DeviceConfig.NEXUS_5.copy(
- softButtons = false
- ),
- renderingMode = SessionParams.RenderingMode.SHRINK
- ).runTest("shrinks to wrap view") {
- val view = buildView(
- context,
- ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- )
- )
- snapshot(view, "rendering-mode-shrink")
- }
- }
-
- @Ignore("b/245941625")
- @Test
- fun `renders full device with RenderingMode NORMAL`() {
- Paparazzi(
- snapshotHandler = TestSnapshotVerifier(true),
- deviceConfig = DeviceConfig.NEXUS_5.copy(
- softButtons = false
- ),
- renderingMode = SessionParams.RenderingMode.NORMAL
- ).runTest("renders full device with RenderingMode NORMAL") {
- val view = buildView(
- context,
- ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- )
- )
- snapshot(view, "rendering-mode-normal")
- }
- }
-
- private fun Paparazzi.runTest(name: String, body: Paparazzi.() -> Unit) {
- try {
- prepare(Description.createTestDescription(this@RenderingModeTest::class.java, name))
- body()
- } finally {
- close()
- }
- }
-
- private fun buildView(
- context: Context,
- rootLayoutParams: ViewGroup.LayoutParams? = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT
- )
- ) =
- LinearLayout(context).apply {
- orientation = LinearLayout.VERTICAL
- rootLayoutParams?.let { layoutParams = it }
- addView(
- TextView(context).apply {
- id = 1
- text = "Text View Sample"
- }
- )
-
- addView(
- View(context).apply {
- id = 2
- layoutParams = LinearLayout.LayoutParams(100, 100)
- contentDescription = "Content Description Sample"
- }
- )
-
- addView(
- View(context).apply {
- id = 3
- layoutParams = LinearLayout.LayoutParams(100, 100).apply {
- setMarginsRelative(20, 20, 20, 20)
- }
- contentDescription = "Margin Sample"
- }
- )
-
- addView(
- View(context).apply {
- id = 4
- layoutParams = LinearLayout.LayoutParams(100, 100).apply {
- setMarginsRelative(20, 20, 20, 20)
- }
- foreground = GradientDrawable(
- GradientDrawable.Orientation.TL_BR,
- intArrayOf(Color.YELLOW, Color.BLUE)
- ).apply {
- shape = GradientDrawable.OVAL
- }
- contentDescription = "Foreground Drawable"
- }
- )
-
- addView(
- Button(context).apply {
- id = 5
- layoutParams = LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- ).apply {
- gravity = Gravity.CENTER
- }
- text = "Button Sample"
- }
- )
- }
-}
-
-private class TestSnapshotVerifier(val writeImages: Boolean = false) : SnapshotHandler {
- override fun newFrameHandler(
- snapshot: Snapshot,
- frameCount: Int,
- fps: Int
- ): SnapshotHandler.FrameHandler {
- return object : SnapshotHandler.FrameHandler {
- override fun handle(image: BufferedImage) {
- val expected = File("src/test/resources/${snapshot.name}.png")
- if (writeImages) {
- ImageIO.write(image, "png", expected)
- } else {
- ImageUtils.assertImageSimilar(
- relativePath = expected.path,
- image = image,
- goldenImage = ImageIO.read(expected),
- maxPercentDifferent = 0.1
- )
- }
- }
-
- override fun close() = Unit
- }
- }
-
- override fun close() = Unit
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt
deleted file mode 100644
index b9afe6e..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt
+++ /dev/null
@@ -1,152 +0,0 @@
-package app.cash.paparazzi.accessibility
-
-import android.content.Context
-import android.graphics.Color
-import android.graphics.drawable.GradientDrawable
-import android.graphics.drawable.GradientDrawable.OVAL
-import android.graphics.drawable.GradientDrawable.Orientation.TL_BR
-import android.view.Gravity
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.LinearLayout
-import android.widget.TextView
-import app.cash.paparazzi.DeviceConfig
-import app.cash.paparazzi.Paparazzi
-import app.cash.paparazzi.Snapshot
-import app.cash.paparazzi.SnapshotHandler
-import app.cash.paparazzi.internal.ImageUtils
-import java.awt.image.BufferedImage
-import java.io.File
-import javax.imageio.ImageIO
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-
-class AccessibilityRenderExtensionTest {
- private val snapshotHandler = TestSnapshotVerifier()
-
- @get:Rule
- val paparazzi = Paparazzi(
- deviceConfig = DeviceConfig.NEXUS_5.copy(
- // Needed to render accessibility content next to main content.
- screenWidth = DeviceConfig.NEXUS_5.screenWidth * 2,
- softButtons = false
- ),
- snapshotHandler = snapshotHandler,
- renderExtensions = setOf(AccessibilityRenderExtension())
- )
-
- @Ignore("b/245941625")
- @Test
- fun `verify baseline`() {
- val view = buildView(paparazzi.context)
- paparazzi.snapshot(view, name = "accessibility")
- }
-
- @Ignore("b/245941625")
- @Test
- fun `test without layout params set`() {
- val view = buildView(paparazzi.context, null)
- paparazzi.snapshot(view, name = "without-layout-params")
- }
-
- @Ignore("b/245941625")
- @Test
- fun `verify changing view hierarchy order doesn't change accessibility colors`() {
- val view = buildView(paparazzi.context).apply {
- addView(
- View(context).apply { contentDescription = "Empty View" },
- 0,
- LinearLayout.LayoutParams(0, 0)
- )
- }
- paparazzi.snapshot(view, name = "accessibility-new-view")
- }
-
- private fun buildView(
- context: Context,
- rootLayoutParams: ViewGroup.LayoutParams? = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT
- )
- ) =
- LinearLayout(context).apply {
- orientation = LinearLayout.VERTICAL
- rootLayoutParams?.let { layoutParams = it }
- addView(
- TextView(context).apply {
- id = 1
- text = "Text View Sample"
- }
- )
-
- addView(
- View(context).apply {
- id = 2
- layoutParams = LinearLayout.LayoutParams(100, 100)
- contentDescription = "Content Description Sample"
- }
- )
-
- addView(
- View(context).apply {
- id = 3
- layoutParams = LinearLayout.LayoutParams(100, 100).apply {
- setMarginsRelative(20, 20, 20, 20)
- }
- contentDescription = "Margin Sample"
- }
- )
-
- addView(
- View(context).apply {
- id = 4
- layoutParams = LinearLayout.LayoutParams(100, 100).apply {
- setMarginsRelative(20, 20, 20, 20)
- }
- foreground = GradientDrawable(TL_BR, intArrayOf(Color.YELLOW, Color.BLUE)).apply {
- shape = OVAL
- }
- contentDescription = "Foreground Drawable"
- }
- )
-
- addView(
- Button(context).apply {
- id = 5
- layoutParams = LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
- ).apply {
- gravity = Gravity.CENTER
- }
- text = "Button Sample"
- }
- )
- }
-
- private class TestSnapshotVerifier : SnapshotHandler {
- override fun newFrameHandler(
- snapshot: Snapshot,
- frameCount: Int,
- fps: Int
- ): SnapshotHandler.FrameHandler {
- return object : SnapshotHandler.FrameHandler {
- override fun handle(image: BufferedImage) {
- val expected = File("src/test/resources/${snapshot.name}.png")
- ImageUtils.assertImageSimilar(
- relativePath = expected.path,
- image = image,
- goldenImage = ImageIO.read(expected),
- maxPercentDifferent = 0.1
- )
- }
-
- override fun close() = Unit
- }
- }
-
- override fun close() = Unit
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziJsonTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziJsonTest.kt
deleted file mode 100644
index 9752037..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziJsonTest.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal
-
-import app.cash.paparazzi.TestName
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.Test
-
-class PaparazziJsonTest {
- @Test
- fun testName() {
- val adapter = PaparazziJson.moshi.adapter(TestName::class.java)
- val testName = TestName("app.cash.paparazzi", "CelebrityTest", "testSettings")
- val json = "\"app.cash.paparazzi.CelebrityTest#testSettings\""
- assertThat(adapter.toJson(testName)).isEqualTo(json)
- assertThat(adapter.fromJson(json)).isEqualTo(testName)
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt
deleted file mode 100644
index 89d7823..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package app.cash.paparazzi.internal
-
-import app.cash.paparazzi.internal.PaparazziLogger.MultipleFailuresException
-import java.io.FileNotFoundException
-import org.assertj.core.api.Assertions.assertThat
-import org.assertj.core.api.Assertions.fail
-import org.junit.Test
-
-class PaparazziLoggerTest {
- @Test
- fun testNoErrors() {
- val logger = PaparazziLogger()
-
- try {
- logger.assertNoErrors()
- } catch (ignored: Exception) {
- fail("Did not expect exception to be thrown: $ignored")
- }
- }
-
- @Test
- fun testSingleError() {
- val logger = PaparazziLogger()
- logger.error(FileNotFoundException("error1"), null)
-
- try {
- logger.assertNoErrors()
- fail("Expected exception to be thrown")
- } catch (ignored: Exception) {
- assertThat(ignored).isInstanceOf(FileNotFoundException::class.java)
- }
- }
-
- @Test
- fun testMultipleErrors() {
- val logger = PaparazziLogger()
- logger.error(FileNotFoundException("error1"), null)
- logger.error("tag", null, IllegalStateException("error2"), null, null)
-
- try {
- logger.assertNoErrors()
- fail("Expected exceptions to be thrown")
- } catch (ignored: Exception) {
- assertThat(ignored).isInstanceOf(MultipleFailuresException::class.java)
- assertThat(ignored.message).contains("There were 2 errors:")
- assertThat(ignored.message).contains("java.io.FileNotFoundException: error1")
- assertThat(ignored.message).contains("java.lang.IllegalStateException: error2")
- }
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/parsers/InMemoryParserTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/parsers/InMemoryParserTest.kt
deleted file mode 100644
index 9a032e3..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/parsers/InMemoryParserTest.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-package app.cash.paparazzi.internal.parsers
-
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.Test
-import org.xmlpull.v1.XmlPullParserException
-
-class InMemoryParserTest {
- @Test
- fun parse() {
- val root = parseResourceTree("plus_sign.xml")
- val parser = RealInMemoryParser(root)
-
- assertThat(parser.name).isNull() // START_DOCUMENT
- assertThat(parser.depth).isEqualTo(0)
-
- parser.next() // START_TAG = "vector"
-
- assertThat(parser.name).isEqualTo(VECTOR_TAG_NAME)
- assertThat(parser.depth).isEqualTo(1)
- assertThat(parser.attributeCount).isEqualTo(4)
-
- assertThat(parser.getAttributeName(0)).isEqualTo("height")
- assertThat(parser.getAttributeName(1)).isEqualTo("viewportHeight")
- assertThat(parser.getAttributeName(2)).isEqualTo("viewportWidth")
- assertThat(parser.getAttributeName(3)).isEqualTo("width")
-
- assertThat(parser.getAttributeNamespace(0)).isEqualTo(ANDROID_NAMESPACE)
- assertThat(parser.getAttributeNamespace(1)).isEqualTo(ANDROID_NAMESPACE)
- assertThat(parser.getAttributeNamespace(2)).isEqualTo(ANDROID_NAMESPACE)
- assertThat(parser.getAttributeNamespace(3)).isEqualTo(ANDROID_NAMESPACE)
-
- assertThat(parser.getAttributePrefix(0)).isEqualTo(ANDROID_PREFIX)
- assertThat(parser.getAttributePrefix(1)).isEqualTo(ANDROID_PREFIX)
- assertThat(parser.getAttributePrefix(2)).isEqualTo(ANDROID_PREFIX)
- assertThat(parser.getAttributePrefix(3)).isEqualTo(ANDROID_PREFIX)
-
- assertThat(parser.getAttributeValue(0)).isEqualTo("24dp")
- assertThat(parser.getAttributeValue(1)).isEqualTo("40")
- assertThat(parser.getAttributeValue(2)).isEqualTo("40")
- assertThat(parser.getAttributeValue(3)).isEqualTo("24dp")
-
- parser.next() // START_TAG = "path"
-
- assertThat(parser.name).isEqualTo(PATH_TAG_NAME)
- assertThat(parser.depth).isEqualTo(2)
- assertThat(parser.attributeCount).isEqualTo(2)
-
- assertThat(parser.getAttributeName(0)).isEqualTo(FILL_COLOR_ATTR_NAME)
- assertThat(parser.getAttributeName(1)).isEqualTo(PATH_DATA_ATTR_NAME)
-
- assertThat(parser.getAttributeNamespace(0)).isEqualTo(ANDROID_NAMESPACE)
- assertThat(parser.getAttributeNamespace(1)).isEqualTo(ANDROID_NAMESPACE)
-
- assertThat(parser.getAttributePrefix(0)).isEqualTo(ANDROID_PREFIX)
- assertThat(parser.getAttributePrefix(1)).isEqualTo(ANDROID_PREFIX)
-
- assertThat(parser.getAttributeValue(0)).isEqualTo("#999999")
- assertThat(parser.getAttributeValue(1)).isNotNull // pathData
-
- parser.next() // END_TAG = "path"
-
- assertThat(parser.name).isEqualTo(PATH_TAG_NAME)
- assertThat(parser.depth).isEqualTo(2)
-
- parser.next() // END_TAG = "vector"
-
- assertThat(parser.name).isEqualTo(VECTOR_TAG_NAME)
- assertThat(parser.depth).isEqualTo(1)
-
- parser.next() // END_DOCUMENT
- assertThat(parser.name).isNull() // START_DOCUMENT
- assertThat(parser.depth).isEqualTo(0)
-
- try {
- parser.next()
- } catch (expected: XmlPullParserException) {
- }
- }
-
- private fun parseResourceTree(resourceId: String): TagSnapshot {
- val resourceInputStream = javaClass.classLoader.getResourceAsStream(resourceId)!!
- return ResourceParser(resourceInputStream).createTagSnapshot()
- }
-
- class RealInMemoryParser(private val root: TagSnapshot) : InMemoryParser() {
- override fun rootTag(): TagSnapshot = root
- }
-
- companion object {
- const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"
- const val ANDROID_PREFIX = "android"
-
- const val VECTOR_TAG_NAME = "vector"
- const val PATH_TAG_NAME = "path"
- const val PATH_DATA_ATTR_NAME = "pathData"
- const val FILL_COLOR_ATTR_NAME = "fillColor"
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/parsers/ResourceParserTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/parsers/ResourceParserTest.kt
deleted file mode 100644
index 67402f9..0000000
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/parsers/ResourceParserTest.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2021 Square, Inc.
- *
- * 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 app.cash.paparazzi.internal.parsers
-
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.Test
-
-class ResourceParserTest {
- @Test
- fun parseResource() {
- val root = parseResourceTree("plus_sign.xml")
- assertThat(root.namespace).isEmpty()
- assertThat(root.prefix).isNull()
- assertThat(root.name).isEqualTo(VECTOR_TAG_NAME)
- assertThat(root.hasDeclaredAaptAttrs).isEqualTo(false)
- assertThat(root.next).isNull()
- assertThat(root.attributes).containsExactly(
- AttributeSnapshot(ANDROID_NAMESPACE, ANDROID_PREFIX, "height", "24dp"),
- AttributeSnapshot(ANDROID_NAMESPACE, ANDROID_PREFIX, "viewportHeight", "40"),
- AttributeSnapshot(ANDROID_NAMESPACE, ANDROID_PREFIX, "viewportWidth", "40"),
- AttributeSnapshot(ANDROID_NAMESPACE, ANDROID_PREFIX, "width", "24dp")
- )
-
- val pathElement = root.children.single()
- with(pathElement) {
- assertThat(namespace).isEmpty()
- assertThat(prefix).isNull()
- assertThat(name).isEqualTo(PATH_TAG_NAME)
- assertThat(hasDeclaredAaptAttrs).isEqualTo(false)
- assertThat(next).isNull()
- }
-
- val pathAttributes = pathElement.attributes
- assertThat(pathAttributes).hasSize(2)
- assertThat(pathAttributes[0]).isEqualTo(
- AttributeSnapshot(ANDROID_NAMESPACE, ANDROID_PREFIX, FILL_COLOR_ATTR_NAME, "#999999")
- )
-
- with(pathAttributes[1]) {
- assertThat(namespace).isEqualTo(ANDROID_NAMESPACE)
- assertThat(prefix).isEqualTo(ANDROID_PREFIX)
- assertThat(name).isEqualTo(PATH_DATA_ATTR_NAME)
- assertThat(value).isNotEmpty // don't care about pathData precision
- }
- }
-
- @Test
- fun parseAaptAttrTags() {
- // Since #parseResource covers the basics, this test can be more targeted
-
- val root = parseResourceTree("card_chip.xml")
- assertThat(root.name).isEqualTo(VECTOR_TAG_NAME)
- assertThat(root.hasDeclaredAaptAttrs).isEqualTo(true)
- assertThat(root.next).isNull()
-
- assertThat(root.children).hasSize(2)
-
- val outerPathElement = root.children[0]
- assertThat(outerPathElement.hasDeclaredAaptAttrs).isEqualTo(false)
-
- val groupElement = root.children[1]
- assertThat(groupElement.hasDeclaredAaptAttrs).isEqualTo(true)
-
- assertThat(outerPathElement.next).isEqualTo(groupElement)
-
- val clipPathElement = groupElement.children[0]
- assertThat(clipPathElement.hasDeclaredAaptAttrs).isEqualTo(false)
-
- val innerPathElement1 = groupElement.children[1]
- assertThat(innerPathElement1.hasDeclaredAaptAttrs).isEqualTo(true)
- with(innerPathElement1.attributes[0]) {
- assertThat(name).isEqualTo(PATH_DATA_ATTR_NAME)
- assertThat(this).isNotInstanceOf(AaptAttrSnapshot::class.java)
- }
- with(innerPathElement1.attributes[1] as AaptAttrSnapshot) {
- assertThat(name).isEqualTo(FILL_COLOR_ATTR_NAME)
- assertThat(id).isEqualTo("1")
- assertThat(value).isEqualTo("@aapt:_aapt/aapt1")
- assertThat(bundledTag.name).isEqualTo(GRADIENT_TAG_NAME) // 🎉
- }
-
- val innerPathElement2 = groupElement.children[2]
- assertThat(innerPathElement2.hasDeclaredAaptAttrs).isEqualTo(true)
- with(innerPathElement2.attributes[0]) {
- assertThat(name).isEqualTo(PATH_DATA_ATTR_NAME)
- assertThat(this).isNotInstanceOf(AaptAttrSnapshot::class.java)
- }
- with(innerPathElement2.attributes[1] as AaptAttrSnapshot) {
- assertThat(name).isEqualTo(FILL_COLOR_ATTR_NAME)
- assertThat(id).isEqualTo("2")
- assertThat(value).isEqualTo("@aapt:_aapt/aapt2")
- assertThat(bundledTag.name).isEqualTo(GRADIENT_TAG_NAME) // 🎉
- }
-
- val innerPathElement3 = groupElement.children[3]
- assertThat(innerPathElement3.hasDeclaredAaptAttrs).isEqualTo(true)
- with(innerPathElement3.attributes[0]) {
- assertThat(name).isEqualTo(PATH_DATA_ATTR_NAME)
- assertThat(this).isNotInstanceOf(AaptAttrSnapshot::class.java)
- }
- with(innerPathElement3.attributes[1]) {
- assertThat(name).isEqualTo(FILL_TYPE_ATTR_NAME)
- assertThat(this).isNotInstanceOf(AaptAttrSnapshot::class.java)
- }
- with(innerPathElement3.attributes[2] as AaptAttrSnapshot) {
- assertThat(name).isEqualTo(FILL_COLOR_ATTR_NAME)
- assertThat(id).isEqualTo("3")
- assertThat(value).isEqualTo("@aapt:_aapt/aapt3")
- assertThat(bundledTag.name).isEqualTo(GRADIENT_TAG_NAME) // 🎉
- }
- }
-
- private fun parseResourceTree(resourceId: String): TagSnapshot {
- val resourceInputStream = javaClass.classLoader.getResourceAsStream(resourceId)!!
- return ResourceParser(resourceInputStream).createTagSnapshot()
- }
-
- companion object {
- const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android"
- const val ANDROID_PREFIX = "android"
-
- const val VECTOR_TAG_NAME = "vector"
- const val PATH_TAG_NAME = "path"
- const val PATH_DATA_ATTR_NAME = "pathData"
- const val FILL_COLOR_ATTR_NAME = "fillColor"
- const val FILL_TYPE_ATTR_NAME = "fillType"
- const val GRADIENT_TAG_NAME = "gradient"
- }
-}
diff --git a/external/paparazzi/paparazzi/src/test/resources/accessibility-new-view.png b/external/paparazzi/paparazzi/src/test/resources/accessibility-new-view.png
deleted file mode 100644
index 57f25b5a..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/accessibility-new-view.png
+++ /dev/null
Binary files differ
diff --git a/external/paparazzi/paparazzi/src/test/resources/accessibility.png b/external/paparazzi/paparazzi/src/test/resources/accessibility.png
deleted file mode 100644
index d7f3a16..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/accessibility.png
+++ /dev/null
Binary files differ
diff --git a/external/paparazzi/paparazzi/src/test/resources/card_chip.xml b/external/paparazzi/paparazzi/src/test/resources/card_chip.xml
deleted file mode 100644
index a9cb398..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/card_chip.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--Copyright Square, Inc.-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt" android:width="42dp" android:height="34dp" android:viewportWidth="42" android:viewportHeight="34">
- <path android:pathData="M36.795 0H5.205C2.333 0 0 2.384 0 5.318v22.374c0 2.934 2.333 5.318 5.205 5.318h31.59c2.872 0 5.205-2.384 5.205-5.318V5.318C41.955 2.384 39.622 0 36.795 0z" android:fillColor="#666666"/>
- <group>
- <clip-path android:pathData="M0.314 21.549h11.981c0.404 0 0.808 0.183 1.122 0.504 1.48 1.559 3.5 2.338 6.058 2.338h0.224c2.378 0 3.814-0.825 3.814-2.109 0-1.192-1.211-1.742-4.711-3.072-3.097-1.146-7.18-3.163-7.45-7.748H0.27v0.459h0.404v9.17H0.27v0.458h0.045zm20.866 7.977c5.519-0.504 8.93-3.53 8.93-7.977 0-4.31-3.994-6.281-7.898-7.611-2.02-0.78-3.5-1.421-4.128-2.476h-6.058c0.27 4.172 4.083 6.052 7 7.107 3.32 1.237 5.115 1.97 5.115 3.713 0 1.742-1.705 2.797-4.487 2.797H19.43c-2.737 0-4.936-0.871-6.507-2.568-0.18-0.183-0.403-0.275-0.628-0.275H0.27v0.459h0.403v4.997c0 1.238 0.494 2.384 1.257 3.21L1.705 31.13l0.314 0.32 0.27-0.274c0.807 0.687 1.795 1.1 2.916 1.1h9.02l0.493-2.568c0.045-0.137-0.045-0.229-0.18-0.275-1.704-0.504-3.275-1.33-4.666-2.475-0.134-0.138-0.18-0.321-0.045-0.459 0.135-0.137 0.314-0.183 0.449-0.046 1.346 1.055 2.827 1.88 4.442 2.338 0.449 0.138 0.718 0.596 0.629 1.055l-0.45 2.43h5.026l0.45-2.063c0.089-0.367 0.403-0.642 0.807-0.688zM0.314 10.774h10.994c0.135-5.364 4.801-7.61 9.154-7.931 0.09-0.046 0.18-0.092 0.18-0.23L21 0.644H5.205c-1.121 0-2.109 0.412-2.916 1.1l-0.27-0.23L1.705 1.88 1.93 2.11C1.167 2.934 0.673 4.08 0.673 5.318v4.997H0.27v0.458h0.045zm41.327 11.417H30.738c-0.315 4.447-3.904 7.518-9.513 7.977-0.09 0-0.18 0.092-0.225 0.183l-0.404 1.926H36.75c1.122 0 2.11-0.413 2.917-1.1l0.27 0.275 0.313-0.321-0.224-0.23c0.808-0.825 1.301-1.97 1.301-3.209v-4.997h0.36L41.64 22.19zm-0.314-11.875V5.319c0-1.238-0.493-2.385-1.301-3.21L40.25 1.88l-0.314-0.367-0.224 0.23c-0.808-0.688-1.795-1.1-2.917-1.1h-9.333l-0.539 2.75c-0.044 0.092 0.045 0.23 0.135 0.275 1.212 0.458 2.378 1.1 3.455 1.834 0.135 0.092 0.18 0.32 0.09 0.458-0.045 0.092-0.18 0.138-0.27 0.138-0.044 0-0.134 0-0.179-0.046-1.032-0.688-2.109-1.284-3.276-1.696-0.403-0.138-0.673-0.596-0.583-1.009l0.539-2.613h-5.16l-0.36 2.017c-0.09 0.413-0.403 0.688-0.807 0.734-4.039 0.32-8.391 2.384-8.481 7.29h5.878c-0.045-0.138-0.045-0.276-0.045-0.413 0-1.467 1.436-2.384 3.904-2.384 1.795 0 4.577 0.642 6.641 2.476 0.224 0.183 0.494 0.32 0.763 0.32h12.564v-0.458h-0.404zm0 1.146H29.122c-0.404 0-0.852-0.183-1.211-0.458-1.93-1.697-4.533-2.339-6.193-2.339-0.538 0-3.23 0.092-3.23 1.697 0 1.33 1.57 2.017 3.948 2.934 4.128 1.421 8.302 3.484 8.302 8.253h10.948V21.09h-0.359v-9.17h0.36v-0.458h-0.36z"/>
- <path android:pathData="M0.314 21.549h11.981c0.404 0 0.808 0.183 1.122 0.504 1.48 1.559 3.5 2.338 6.058 2.338h0.224c2.378 0 3.814-0.825 3.814-2.109 0-1.192-1.211-1.742-4.711-3.072-3.097-1.146-7.18-3.163-7.45-7.748H0.27v0.459h0.404v9.17H0.27v0.458h0.045zm20.866 7.977c5.519-0.504 8.93-3.53 8.93-7.977 0-4.31-3.994-6.281-7.898-7.611-2.02-0.78-3.5-1.421-4.128-2.476h-6.058c0.27 4.172 4.083 6.052 7 7.107 3.32 1.237 5.115 1.97 5.115 3.713 0 1.742-1.705 2.797-4.487 2.797H19.43c-2.737 0-4.936-0.871-6.507-2.568-0.18-0.183-0.403-0.275-0.628-0.275H0.27v0.459h0.403v4.997c0 1.238 0.494 2.384 1.257 3.21L1.705 31.13l0.314 0.32 0.27-0.274c0.807 0.687 1.795 1.1 2.916 1.1h9.02l0.493-2.568c0.045-0.137-0.045-0.229-0.18-0.275-1.704-0.504-3.275-1.33-4.666-2.475-0.134-0.138-0.18-0.321-0.045-0.459 0.135-0.137 0.314-0.183 0.449-0.046 1.346 1.055 2.827 1.88 4.442 2.338 0.449 0.138 0.718 0.596 0.629 1.055l-0.45 2.43h5.026l0.45-2.063c0.089-0.367 0.403-0.642 0.807-0.688zM0.314 10.774h10.994c0.135-5.364 4.801-7.61 9.154-7.931 0.09-0.046 0.18-0.092 0.18-0.23L21 0.644H5.205c-1.121 0-2.109 0.412-2.916 1.1l-0.27-0.23L1.705 1.88 1.93 2.11C1.167 2.934 0.673 4.08 0.673 5.318v4.997H0.27v0.458h0.045zm41.327 11.417H30.738c-0.315 4.447-3.904 7.518-9.513 7.977-0.09 0-0.18 0.092-0.225 0.183l-0.404 1.926H36.75c1.122 0 2.11-0.413 2.917-1.1l0.27 0.275 0.313-0.321-0.224-0.23c0.808-0.825 1.301-1.97 1.301-3.209v-4.997h0.36L41.64 22.19zm-0.314-11.875V5.319c0-1.238-0.493-2.385-1.301-3.21L40.25 1.88l-0.314-0.367-0.224 0.23c-0.808-0.688-1.795-1.1-2.917-1.1h-9.333l-0.539 2.75c-0.044 0.092 0.045 0.23 0.135 0.275 1.212 0.458 2.378 1.1 3.455 1.834 0.135 0.092 0.18 0.32 0.09 0.458-0.045 0.092-0.18 0.138-0.27 0.138-0.044 0-0.134 0-0.179-0.046-1.032-0.688-2.109-1.284-3.276-1.696-0.403-0.138-0.673-0.596-0.583-1.009l0.539-2.613h-5.16l-0.36 2.017c-0.09 0.413-0.403 0.688-0.807 0.734-4.039 0.32-8.391 2.384-8.481 7.29h5.878c-0.045-0.138-0.045-0.276-0.045-0.413 0-1.467 1.436-2.384 3.904-2.384 1.795 0 4.577 0.642 6.641 2.476 0.224 0.183 0.494 0.32 0.763 0.32h12.564v-0.458h-0.404zm0 1.146H29.122c-0.404 0-0.852-0.183-1.211-0.458-1.93-1.697-4.533-2.339-6.193-2.339-0.538 0-3.23 0.092-3.23 1.697 0 1.33 1.57 2.017 3.948 2.934 4.128 1.421 8.302 3.484 8.302 8.253h10.948V21.09h-0.359v-9.17h0.36v-0.458h-0.36z">
- <aapt:attr name="android:fillColor">
- <gradient android:startY="3.4928" android:startX="1.38832" android:endY="46.3417" android:endX="68.7929" android:type="linear">
- <item android:offset="0" android:color="#FFFFFFFF"/>
- <item android:offset="0.4081" android:color="#FFC7B299"/>
- <item android:offset="1" android:color="#FF998675"/>
- </gradient>
- </aapt:attr>
- </path>
- <path android:pathData="M0.314 21.549h11.981c0.404 0 0.808 0.183 1.122 0.504 1.48 1.559 3.5 2.338 6.058 2.338h0.224c2.378 0 3.814-0.825 3.814-2.109 0-1.192-1.211-1.742-4.711-3.072-3.097-1.146-7.18-3.163-7.45-7.748H0.27v0.459h0.404v9.17H0.27v0.458h0.045zm20.866 7.977c5.519-0.504 8.93-3.53 8.93-7.977 0-4.31-3.994-6.281-7.898-7.611-2.02-0.78-3.5-1.421-4.128-2.476h-6.058c0.27 4.172 4.083 6.052 7 7.107 3.32 1.237 5.115 1.97 5.115 3.713 0 1.742-1.705 2.797-4.487 2.797H19.43c-2.737 0-4.936-0.871-6.507-2.568-0.18-0.183-0.403-0.275-0.628-0.275H0.27v0.459h0.403v4.997c0 1.238 0.494 2.384 1.257 3.21L1.705 31.13l0.314 0.32 0.27-0.274c0.807 0.687 1.795 1.1 2.916 1.1h9.02l0.493-2.568c0.045-0.137-0.045-0.229-0.18-0.275-1.704-0.504-3.275-1.33-4.666-2.475-0.134-0.138-0.18-0.321-0.045-0.459 0.135-0.137 0.314-0.183 0.449-0.046 1.346 1.055 2.827 1.88 4.442 2.338 0.449 0.138 0.718 0.596 0.629 1.055l-0.45 2.43h5.026l0.45-2.063c0.089-0.367 0.403-0.642 0.807-0.688zM0.314 10.774h10.994c0.135-5.364 4.801-7.61 9.154-7.931 0.09-0.046 0.18-0.092 0.18-0.23L21 0.644H5.205c-1.121 0-2.109 0.412-2.916 1.1l-0.27-0.23L1.705 1.88 1.93 2.11C1.167 2.934 0.673 4.08 0.673 5.318v4.997H0.27v0.458h0.045zm41.327 11.417H30.738c-0.315 4.447-3.904 7.518-9.513 7.977-0.09 0-0.18 0.092-0.225 0.183l-0.404 1.926H36.75c1.122 0 2.11-0.413 2.917-1.1l0.27 0.275 0.313-0.321-0.224-0.23c0.808-0.825 1.301-1.97 1.301-3.209v-4.997h0.36L41.64 22.19zm-0.314-11.875V5.319c0-1.238-0.493-2.385-1.301-3.21L40.25 1.88l-0.314-0.367-0.224 0.23c-0.808-0.688-1.795-1.1-2.917-1.1h-9.333l-0.539 2.75c-0.044 0.092 0.045 0.23 0.135 0.275 1.212 0.458 2.378 1.1 3.455 1.834 0.135 0.092 0.18 0.32 0.09 0.458-0.045 0.092-0.18 0.138-0.27 0.138-0.044 0-0.134 0-0.179-0.046-1.032-0.688-2.109-1.284-3.276-1.696-0.403-0.138-0.673-0.596-0.583-1.009l0.539-2.613h-5.16l-0.36 2.017c-0.09 0.413-0.403 0.688-0.807 0.734-4.039 0.32-8.391 2.384-8.481 7.29h5.878c-0.045-0.138-0.045-0.276-0.045-0.413 0-1.467 1.436-2.384 3.904-2.384 1.795 0 4.577 0.642 6.641 2.476 0.224 0.183 0.494 0.32 0.763 0.32h12.564v-0.458h-0.404zm0 1.146H29.122c-0.404 0-0.852-0.183-1.211-0.458-1.93-1.697-4.533-2.339-6.193-2.339-0.538 0-3.23 0.092-3.23 1.697 0 1.33 1.57 2.017 3.948 2.934 4.128 1.421 8.302 3.484 8.302 8.253h10.948V21.09h-0.359v-9.17h0.36v-0.458h-0.36z">
- <aapt:attr name="android:fillColor">
- <gradient android:startY="31.3798" android:startX="42.1542" android:endY="-9.12049" android:endX="13.8976" android:type="linear">
- <item android:offset="0" android:color="#FFF1EAE2"/>
- <item android:offset="0.149949" android:color="#FFF3ECE3"/>
- <item android:offset="0.319891" android:color="#FFF4EDE4"/>
- <item android:offset="0.509302" android:color="#FFEFE6DB"/>
- <item android:offset="0.707905" android:color="#FFECE4DB"/>
- <item android:offset="1" android:color="#FFF1F1F1"/>
- </gradient>
- </aapt:attr>
- </path>
- <path android:pathData="M1.25 0.5C1.08 0.775 1.166 1 1.441 1S2.08 0.775 2.25 0.5C2.42 0.225 2.334 0 2.059 0S1.42 0.225 1.25 0.5zM24 1.03c0 0.565 0.225 0.89 0.5 0.72 0.275-0.17 0.5-0.633 0.5-1.03C25 0.324 24.775 0 24.5 0S24 0.464 24 1.03zm4-0.78c0 0.138 0.113 0.25 0.25 0.25s0.25-0.112 0.25-0.25S28.387 0 28.25 0 28 0.113 28 0.25zm-8.181 2C19.661 2.663 19.749 3 20.016 3 20.282 3 20.5 2.663 20.5 2.25S20.412 1.5 20.303 1.5c-0.108 0-0.326 0.337-0.484 0.75zM24 2.75C24 2.888 24.113 3 24.25 3s0.25-0.112 0.25-0.25-0.113-0.25-0.25-0.25S24 2.612 24 2.75zm-4.76 1.78c-0.45 1.42 0.05 1.796 0.721 0.543 0.326-0.609 0.357-1.127 0.077-1.3-0.256-0.158-0.615 0.182-0.797 0.757zM22.83 4c-0.977 3.02-0.495 6.254 0.669 4.5 0.274-0.412 0.448-1.088 0.387-1.5-0.06-0.412 0.046-0.998 0.236-1.301 0.191-0.303 0.033-0.978-0.351-1.5C23.19 3.412 23.03 3.378 22.829 4zm2.895 1.875C24.304 9.252 23.56 14.5 24.5 14.5c0.275 0 0.5-0.575 0.5-1.278C25 11.64 26.04 7.34 26.504 7c0.188-0.138 0.493-0.869 0.678-1.625 0.501-2.046-0.536-1.69-1.457 0.5zM32 4.75C32 4.888 32.112 5 32.25 5s0.25-0.112 0.25-0.25-0.112-0.25-0.25-0.25S32 4.612 32 4.75zM0.508 5.875c0.004 0.206 0.217 0.706 0.473 1.11 0.576 0.911 1.251 0.341 0.846-0.714-0.298-0.779-1.333-1.09-1.32-0.396zM13 6.029c0 0.292 0.225 0.391 0.5 0.221S14 5.842 14 5.72c0-0.12-0.225-0.22-0.5-0.22S13 5.739 13 6.03zm20.54 0.173c-0.415 0.5-0.424 0.753-0.031 0.885C34.584 7.444 29.094 22 27.884 22c-0.223 0-1.383-0.9-2.576-2-3.16-2.913-3.467-2.449-0.421 0.636l2.603 2.635-1.295 1.398c-1.703 1.835-1.092 2.398 0.719 0.663 1.881-1.802 5.678-9.57 7.284-14.905C34.914 8.05 35.5 5.97 35.5 5.804c0-0.58-1.382-0.298-1.96 0.399zM2.876 6.33c0.344 0.139 0.906 0.139 1.25 0S4.188 6.079 3.5 6.079 2.531 6.193 2.875 6.331zM5 6.5C5 6.775 5.225 7 5.5 7S6 6.775 6 6.5 5.775 6 5.5 6 5 6.225 5 6.5zm10.5 0.25C15.5 6.888 15.613 7 15.75 7S16 6.888 16 6.75 15.887 6.5 15.75 6.5 15.5 6.612 15.5 6.75zM13 7.25c0 0.138 0.113 0.25 0.25 0.25s0.25-0.112 0.25-0.25S13.387 7 13.25 7 13 7.112 13 7.25zM8.5 8.146C6.987 8.373 5.02 8.447 4.128 8.311 3.098 8.155 2.245 8.327 1.79 8.783 1.395 9.177 0.83 9.5 0.535 9.5 0.241 9.5 0 10.063 0 10.75 0 11.943 0.136 12 2.966 12c2.761 0 3.044 0.11 4.096 1.587 0.656 0.922 1.216 1.329 1.336 0.971 0.112-0.338-0.191-1.053-0.674-1.587-0.484-0.534-0.788-0.983-0.676-0.998 0.111-0.015 1.954-0.21 4.096-0.436 2.142-0.224 3.995-0.51 4.12-0.634 0.124-0.124-0.05-0.81-0.387-1.524-0.723-1.532-2.324-1.841-6.377-1.233zM16 7.75C16 7.888 16.113 8 16.25 8s0.25-0.112 0.25-0.25-0.113-0.25-0.25-0.25S16 7.612 16 7.75zm12.278 2.778c-1.78 3.966-1.386 4.36 0.472 0.472 0.785-1.643 1.308-3.108 1.162-3.255-0.146-0.146-0.882 1.106-1.634 2.783zM13.334 8.834c-0.184 0.183-0.484 0.183-0.668 0C12.483 8.65 12.633 8.5 13 8.5s0.517 0.15 0.334 0.334zm4.968 0.541c-1.22 4.022-1.857 8.726-1.305 9.62 0.555 0.898 1.384-2.032 1.761-6.225 0.172-1.915 0.423-3.658 0.557-3.875 0.134-0.217 0.021-0.395-0.252-0.395-0.272 0-0.615 0.394-0.761 0.875zM4.5 9.25c0 0.137-0.112 0.25-0.25 0.25S4 9.387 4 9.25 4.112 9 4.25 9 4.5 9.113 4.5 9.25zm2 0c0 0.137-0.112 0.25-0.25 0.25S6 9.387 6 9.25 6.112 9 6.25 9 6.5 9.113 6.5 9.25zm4.375 0.108c-0.756 0.114-1.993 0.114-2.75 0C7.369 9.243 7.987 9.15 9.5 9.15c1.512 0 2.132 0.093 1.375 0.208zM22.08 11.93c-0.698 2.33-0.737 3.226-0.123 2.847 0.494-0.305 1.282-4.204 0.923-4.564-0.121-0.12-0.481 0.652-0.8 1.717zM3.5 13.5c0 0.367 0.15 0.517 0.333 0.334 0.183-0.184 0.183-0.484 0-0.668C3.65 12.983 3.5 13.133 3.5 13.5zm1-0.25c0 0.137 0.112 0.25 0.25 0.25S5 13.387 5 13.25 4.888 13 4.75 13 4.5 13.113 4.5 13.25zm28.334 2.584c-0.184 0.183-0.334 0.565-0.334 0.85 0 0.313 0.233 0.283 0.592-0.076 0.325-0.325 0.475-0.708 0.333-0.85-0.142-0.142-0.408-0.108-0.591 0.076zM15.5 16.25c0 0.137 0.113 0.25 0.25 0.25S16 16.387 16 16.25 15.887 16 15.75 16s-0.25 0.113-0.25 0.25zm3.959 2.375c-0.023 0.344-0.137 1.2-0.254 1.902-0.156 0.938 0.188 1.662 1.291 2.719 1.452 1.391 2.13 3.2 0.919 2.452-0.399-0.247-0.479-0.085-0.25 0.511 0.184 0.48 0.335 1.305 0.335 1.832 0 0.527 0.242 0.959 0.538 0.959 0.296 0 0.497-0.619 0.447-1.375-0.139-2.099-0.066-2.203 1.091-1.584 0.928 0.497 1.031 0.46 0.75-0.274C24.146 25.301 24 24.824 24 24.71c0-0.115-0.281-0.212-0.625-0.215-0.343-0.003-1.336-0.736-2.204-1.631-1.391-1.431-1.5-1.736-0.91-2.543 0.683-0.934 0.495-2.32-0.314-2.32-0.246 0-0.465 0.282-0.488 0.625zM6.75 21c-0.17 0.275-0.07 0.5 0.22 0.5 0.292 0 0.53-0.225 0.53-0.5s-0.099-0.5-0.22-0.5c-0.122 0-0.36 0.225-0.53 0.5zm9 0.09c-0.825 0.245-2.328 0.325-3.339 0.177-1.258-0.183-2.075-0.032-2.586 0.48-0.412 0.411-1.159 0.823-1.661 0.916C5.802 23.1 2.816 24.16 3.378 24.36c0.345 0.124 0.501 0.431 0.345 0.683C3.569 25.294 4.13 25.5 4.971 25.5 5.81 25.5 6.5 25.725 6.5 26s-0.956 0.503-2.125 0.508C2.819 26.514 2.45 26.645 3 27c0.413 0.267 1.699 0.488 2.86 0.492 1.7 0.006 2.05 0.158 1.81 0.788-0.165 0.428-0.6 0.663-0.968 0.521-0.369-0.14-0.803-0.041-0.965 0.222C5.574 29.285 5.932 29.5 6.532 29.5c0.856 0 0.97 0.145 0.534 0.671-0.715 0.861-0.279 1.291 0.977 0.963 0.696-0.183 0.898-0.534 0.688-1.196C8.528 29.304 8.676 29 9.186 29c0.415 0 0.892-0.223 1.06-0.494 0.175-0.284-0.026-0.367-0.471-0.197-1.216 0.467-0.908-0.593 0.349-1.199l1.125-0.543-1.125-0.033C8.85 26.496 8.62 25.753 9.75 25.319c0.412-0.158 0.75-0.621 0.75-1.03 0-0.658 2.703-1.778 4.31-1.786 0.585-0.003 1.464 4.422 1.266 6.372C16.014 29.494 16.197 30 16.482 30 16.791 30 17 28.576 17 26.47c0-2.225-0.184-3.415-0.5-3.22-0.786 0.485-0.585-0.328 0.33-1.338 1.061-1.173 0.792-1.377-1.08-0.822zm25.285 0.994c-0.019 0.459-0.171 1.19-0.338 1.625-0.2 0.519-0.028 0.791 0.5 0.791 0.875 0 0.97-0.698 0.303-2.25-0.343-0.799-0.437-0.832-0.465-0.166zM10.5 22.25c0 0.137-0.113 0.25-0.25 0.25S10 22.387 10 22.25 10.113 22 10.25 22s0.25 0.113 0.25 0.25zM39 23.5c0 0.366 0.15 0.517 0.334 0.334 0.182-0.184 0.182-0.484 0-0.668C39.15 22.983 39 23.134 39 23.5zM8.634 24.328c-0.338 0.137-1.013 0.146-1.5 0.018-0.486-0.127-0.209-0.238 0.616-0.248 0.825-0.01 1.223 0.093 0.884 0.23zM5 24.75C5 24.887 4.888 25 4.75 25S4.5 24.887 4.5 24.75s0.112-0.25 0.25-0.25S5 24.613 5 24.75zm26.5 0.75c0 0.275 0.238 0.5 0.53 0.5 0.29 0 0.39-0.225 0.22-0.5S31.842 25 31.72 25c-0.121 0-0.22 0.225-0.22 0.5zm6.822 0.54c-0.857 0.826-0.87 1.012-0.164 2.427C38.58 29.311 38.74 30 38.517 30c-0.223 0-0.375 0.394-0.337 0.875 0.048 0.605-0.355 0.924-1.305 1.033-0.86 0.099-1.375-0.079-1.375-0.475 0-0.465-0.148-0.485-0.556-0.076C33.995 32.303 34.96 33 37.225 33c1.465 0 2.26-0.243 2.455-0.75 0.158-0.413 0.547-0.75 0.864-0.75 0.416 0 0.404 0.21-0.045 0.75-0.52 0.627-0.448 0.75 0.439 0.75C41.717 33 42 32.689 42 31.834c0-1.512-0.486-1.968-1.341-1.258-0.852 0.706-1.284 0.331-0.867-0.755C39.965 29.37 40.532 29 41.053 29c1.19 0 1.244-0.85 0.072-1.155-0.834-0.218-0.834-0.232 0-0.287C42.063 27.496 42.429 25 41.5 25c-0.275 0-0.5 0.225-0.5 0.5 0 0.609-1.35 0.67-1.584 0.073-0.091-0.236-0.583-0.026-1.094 0.466zM8 25.72c0 0.122-0.225 0.36-0.5 0.53C7.225 26.42 7 26.32 7 26.03c0-0.292 0.225-0.53 0.5-0.53S8 25.599 8 25.72zm15 1.03c0 0.137 0.113 0.25 0.25 0.25s0.25-0.113 0.25-0.25-0.113-0.25-0.25-0.25S23 26.613 23 26.75zM1.5 27.5c0 0.366 0.15 0.517 0.333 0.334 0.184-0.184 0.184-0.484 0-0.668C1.65 26.983 1.5 27.134 1.5 27.5zm23.532 0.29c0.325 0.39 0.913 0.71 1.308 0.71 1.006 0 0.39-0.823-0.861-1.15-0.85-0.223-0.93-0.144-0.447 0.44zm-10.28 1.335c-0.18 0.894-0.429 1.992-0.554 2.441-0.126 0.448 0.06 0.926 0.412 1.06 0.465 0.178 0.667-0.492 0.736-2.44 0.11-3.047-0.114-3.446-0.594-1.061zm8.341 0.282c-0.078 1.37 0.023 1.65 0.393 1.093 0.603-0.907 0.664-2.349 0.114-2.688-0.22-0.136-0.448 0.582-0.507 1.595zM24.5 29.25c0 0.137 0.113 0.25 0.25 0.25S25 29.387 25 29.25 24.887 29 24.75 29s-0.25 0.113-0.25 0.25zm1.166 0.084c0.184 0.183 0.484 0.183 0.668 0C26.517 29.15 26.366 29 26 29s-0.517 0.15-0.334 0.334zM28 29.75c0 0.137 0.113 0.25 0.25 0.25s0.25-0.113 0.25-0.25-0.113-0.25-0.25-0.25S28 29.613 28 29.75zM1 30.5c0 0.366 0.15 0.517 0.333 0.334 0.183-0.184 0.183-0.484 0-0.668C1.15 29.983 1 30.134 1 30.5zm28-0.25c0 0.137 0.113 0.25 0.25 0.25s0.25-0.113 0.25-0.25S29.387 30 29.25 30 29 30.113 29 30.25zm-7.5 1.5c0 0.137 0.113 0.25 0.25 0.25S22 31.887 22 31.75s-0.113-0.25-0.25-0.25-0.25 0.113-0.25 0.25zm-14 0.75c0.982 0.635 2.5 0.635 2.5 0 0-0.275-0.731-0.496-1.625-0.492C7.142 32.013 6.931 32.132 7.5 32.5zm17.5 0c0.97 0.627 1.5 0.627 1.5 0 0-0.275-0.506-0.496-1.125-0.492-0.91 0.006-0.982 0.1-0.375 0.492z" android:fillType="evenOdd">
- <aapt:attr name="android:fillColor">
- <gradient android:startY="1.5" android:startX="32.5" android:endY="37.0292" android:endX="-0.969948" android:type="linear">
- <item android:offset="0" android:color="#FFECE3DA"/>
- <item android:offset="0.208782" android:color="#FFEBE2D6"/>
- <item android:offset="1" android:color="#FFEBE2D9"/>
- </gradient>
- </aapt:attr>
- </path>
- </group>
-</vector>
diff --git a/external/paparazzi/paparazzi/src/test/resources/plus_sign.xml b/external/paparazzi/paparazzi/src/test/resources/plus_sign.xml
deleted file mode 100644
index 15567605..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/plus_sign.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="40" android:viewportWidth="40" android:width="24dp">
- <path android:fillColor="#999999" android:pathData="M21.5 14c0-0.828-0.672-1.5-1.5-1.5s-1.5 0.672-1.5 1.5v4.5H14c-0.828 0-1.5 0.672-1.5 1.5s0.672 1.5 1.5 1.5h4.5V26c0 0.828 0.672 1.5 1.5 1.5s1.5-0.672 1.5-1.5v-4.5H26c0.828 0 1.5-0.672 1.5-1.5s-0.672-1.5-1.5-1.5h-4.5V14z"/>
-</vector>
diff --git a/external/paparazzi/paparazzi/src/test/resources/rendering-mode-normal.png b/external/paparazzi/paparazzi/src/test/resources/rendering-mode-normal.png
deleted file mode 100644
index e69de29..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/rendering-mode-normal.png
+++ /dev/null
diff --git a/external/paparazzi/paparazzi/src/test/resources/rendering-mode-shrink.png b/external/paparazzi/paparazzi/src/test/resources/rendering-mode-shrink.png
deleted file mode 100644
index e69de29..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/rendering-mode-shrink.png
+++ /dev/null
diff --git a/external/paparazzi/paparazzi/src/test/resources/without-layout-params.png b/external/paparazzi/paparazzi/src/test/resources/without-layout-params.png
deleted file mode 100644
index e3da5cb..0000000
--- a/external/paparazzi/paparazzi/src/test/resources/without-layout-params.png
+++ /dev/null
Binary files differ
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b276acf..e35bc05 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -56,8 +56,6 @@
mockito = "2.25.0"
moshi = "1.13.0"
protobuf = "3.22.3"
-paparazzi = "1.0.0"
-paparazziNative = "2022.1.1-canary-f5f9f71"
skiko = "0.7.7"
spdxGradlePlugin = "0.3.0"
sqldelight = "1.3.0"
@@ -245,11 +243,6 @@
playServicesDevicePerformance = { module = "com.google.android.gms:play-services-deviceperformance", version = "16.0.0" }
playServicesFido = {module = "com.google.android.gms:play-services-fido", version = "20.1.0"}
playServicesWearable = { module = "com.google.android.gms:play-services-wearable", version = "17.1.0" }
-paparazzi = { module = "app.cash.paparazzi:paparazzi", version.ref = "paparazzi" }
-paparazziNativeJvm = { module = "app.cash.paparazzi:layoutlib-native-jdk11", version.ref = "paparazziNative" }
-paparazziNativeLinuxX64 = { module = "app.cash.paparazzi:layoutlib-native-linux", version.ref = "paparazziNative" }
-paparazziNativeMacOsArm64 = { module = "app.cash.paparazzi:layoutlib-native-macarm", version.ref = "paparazziNative" }
-paparazziNativeMacOsX64 = { module = "app.cash.paparazzi:layoutlib-native-macosx", version.ref = "paparazziNative" }
protobuf = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuf" }
protobufCompiler = { module = "com.google.protobuf:protoc", version.ref = "protobuf" }
protobufGradlePlugin = { module = "com.google.protobuf:protobuf-gradle-plugin", version = "0.9.4" }
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 4061606..82e12f6 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -238,7 +238,6 @@
<trusting group="com.google.auto.value"/>
<trusting group="com.google.auto.value" name="auto-value"/>
</trusted-key>
- <trusted-key id="70731C2FFB496DC4E8105AA3604F437C1682DDE5" group="app.cash.paparazzi"/>
<trusted-key id="70CD19BFD9F6C330027D6F260315BFB7970A144F">
<trusting group="com.sun.istack"/>
<trusting group="com.sun.xml.bind"/>
diff --git a/gradlew b/gradlew
index 64c7da7..4019b0b 100755
--- a/gradlew
+++ b/gradlew
@@ -264,8 +264,7 @@
fi
if [ "$compact" == "--strict" ]; then
expanded="-Pandroidx.validateNoUnrecognizedMessages\
- -Pandroidx.verifyUpToDate\
- --no-watch-fs"
+ -Pandroidx.verifyUpToDate"
if [ "$USE_ANDROIDX_REMOTE_BUILD_CACHE" == "" ]; then
expanded="$expanded --offline"
fi
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt
index f77ccb5..9d9228e 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/CanvasBufferedRendererTests.kt
@@ -872,31 +872,34 @@
)
}
- val sharedFdMonitor = CanvasBufferedRendererV34.obtainSharedFdMonitor()!!
- val hbr1 = createHardwareBufferRenderer(sharedFdMonitor)
- val hbr2 = createHardwareBufferRenderer(sharedFdMonitor)
- val hbr3 = createHardwareBufferRenderer(sharedFdMonitor)
+ val sharedFdMonitor = CanvasBufferedRendererV34.obtainSharedFdMonitor()
+ // Monitor is only returned on devices running the vulkan hwui backend
+ if (sharedFdMonitor != null) {
+ val hbr1 = createHardwareBufferRenderer(sharedFdMonitor)
+ val hbr2 = createHardwareBufferRenderer(sharedFdMonitor)
+ val hbr3 = createHardwareBufferRenderer(sharedFdMonitor)
- hbr1.close()
+ hbr1.close()
- assertTrue(sharedFdMonitor.isMonitoring)
+ assertTrue(sharedFdMonitor.isMonitoring)
- hbr2.close()
+ hbr2.close()
- assertTrue(sharedFdMonitor.isMonitoring)
+ assertTrue(sharedFdMonitor.isMonitoring)
- hbr3.close()
+ hbr3.close()
- assertFalse(sharedFdMonitor.isMonitoring)
+ assertFalse(sharedFdMonitor.isMonitoring)
- val sharedFdMonitor2 = CanvasBufferedRendererV34.obtainSharedFdMonitor()!!
- val hbr4 = createHardwareBufferRenderer(sharedFdMonitor2)
+ val sharedFdMonitor2 = CanvasBufferedRendererV34.obtainSharedFdMonitor()!!
+ val hbr4 = createHardwareBufferRenderer(sharedFdMonitor2)
- assertTrue(sharedFdMonitor2.isMonitoring)
+ assertTrue(sharedFdMonitor2.isMonitoring)
- hbr4.close()
+ hbr4.close()
- assertFalse(sharedFdMonitor2.isMonitoring)
+ assertFalse(sharedFdMonitor2.isMonitoring)
+ }
}
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
diff --git a/graphics/graphics-core/src/main/cpp/graphics-core.cpp b/graphics/graphics-core/src/main/cpp/graphics-core.cpp
index 4603022..632d647 100644
--- a/graphics/graphics-core/src/main/cpp/graphics-core.cpp
+++ b/graphics/graphics-core/src/main/cpp/graphics-core.cpp
@@ -460,6 +460,15 @@
return (*env).NewStringUTF(name);
}
+jboolean JniBindings_nIsHwuiUsingVulkanRenderer(JNIEnv*, jclass) {
+ char value[PROP_VALUE_MAX];
+ __system_property_get("ro.hwui.use_vulkan", value);
+ bool device_is_vulkan = strcmp(value, "true") == 0;
+ __system_property_get("debug.hwui.renderer", value);
+ bool is_debug_vulkan = strcmp(value, "skiavk") == 0;
+ return device_is_vulkan || is_debug_vulkan;
+}
+
jint JniBindings_nGetPreviousReleaseFenceFd(JNIEnv *env, jclass,
jlong surfaceControl,
jlong transactionStats) {
@@ -648,6 +657,11 @@
"nSetFrameRate",
"(JJFII)V",
(void *) JniBindings_nSetFrameRate
+ },
+ {
+ "nIsHwuiUsingVulkanRenderer",
+ "()Z",
+ (void *) JniBindings_nIsHwuiUsingVulkanRenderer
}
};
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV34.kt b/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV34.kt
index bc20094..e491d16 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV34.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/CanvasBufferedRendererV34.kt
@@ -25,6 +25,7 @@
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.util.Consumer
+import androidx.graphics.surface.JniBindings
import androidx.hardware.BufferPool
import androidx.hardware.FileDescriptorMonitor
import androidx.hardware.SyncFenceCompat
@@ -179,7 +180,8 @@
private var sharedFdMonitor: SharedFileDescriptorMonitor? = null
fun obtainSharedFdMonitor(): SharedFileDescriptorMonitor? {
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ val isVulkan = JniBindings.nIsHwuiUsingVulkanRenderer()
+ if (Build.VERSION.SDK_INT == Build.VERSION_CODES.UPSIDE_DOWN_CAKE && isVulkan) {
// See b/295332012
monitorLock.withLock {
var monitor = sharedFdMonitor
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlWrapper.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlWrapper.kt
index 6c6b44c..eb87d20 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlWrapper.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlWrapper.kt
@@ -190,6 +190,10 @@
@JvmStatic
@JniVisible
+ external fun nIsHwuiUsingVulkanRenderer(): Boolean
+
+ @JvmStatic
+ @JniVisible
external fun nGetPreviousReleaseFenceFd(surfaceControl: Long, transactionStats: Long): Int
@JvmStatic
diff --git a/graphics/graphics-core/src/main/java/androidx/hardware/FileDescriptorMonitor.kt b/graphics/graphics-core/src/main/java/androidx/hardware/FileDescriptorMonitor.kt
index c31b7f6..ee22309 100644
--- a/graphics/graphics-core/src/main/java/androidx/hardware/FileDescriptorMonitor.kt
+++ b/graphics/graphics-core/src/main/java/androidx/hardware/FileDescriptorMonitor.kt
@@ -39,27 +39,57 @@
private val mIsManagingHandlerThread = AtomicBoolean(false)
private var mExecutor: HandlerThreadExecutor
+ private data class FdSignalPair(val fd: Int, val signalTime: Long)
+ private val pendingFileDescriptors = ArrayList<FdSignalPair>()
+
init {
mExecutor = executor ?: HandlerThreadExecutor("fdcleanup")
mIsManagingHandlerThread.set(manageExecutor)
}
+ private fun closePendingFileDescriptors() {
+ pendingFileDescriptors.sortByDescending { fdSignalTimePair -> fdSignalTimePair.signalTime }
+ while (pendingFileDescriptors.size > MAX_FD) {
+ val fdSignalPair = pendingFileDescriptors.removeLast()
+ try {
+ val fd = fdSignalPair.fd
+ // Re-query the signal time in case the fd was re-used
+ val signalTime = SyncFenceBindings.nGetSignalTime(fd)
+ val diff = signalTime.signalTimeDiffMillis()
+ if (diff > SIGNAL_TIME_DELTA_MILLIS) {
+ SyncFenceBindings.nForceClose(fd)
+ }
+ } catch (_: Throwable) {
+ // Just in case the owner actually does close the fd
+ }
+ }
+ }
+
+ private fun Long.signalTimeDiffMillis(): Long {
+ val now = System.nanoTime()
+ val signalled = this != SyncFenceCompat.SIGNAL_TIME_INVALID &&
+ this != SyncFenceCompat.SIGNAL_TIME_PENDING
+ return if (signalled && now > this) {
+ TimeUnit.NANOSECONDS.toMillis(now - this)
+ } else {
+ -1
+ }
+ }
+
private val mCleanupRunnable = Runnable {
mProcFd.listFiles()?.let { files ->
for (file in files) {
try {
val fd = Integer.parseInt(file.name)
val signalTime = SyncFenceBindings.nGetSignalTime(fd)
- val hasSignaled = signalTime != SyncFenceCompat.SIGNAL_TIME_INVALID &&
- signalTime != SyncFenceCompat.SIGNAL_TIME_PENDING
- val now = System.nanoTime()
- val diff = if (hasSignaled && now > signalTime) {
- TimeUnit.NANOSECONDS.toMillis(now - signalTime)
- } else {
- -1
- }
+ val diff = signalTime.signalTimeDiffMillis()
if (diff > SIGNAL_TIME_DELTA_MILLIS) {
- SyncFenceBindings.nForceClose(fd);
+ // Store the signal time as it can potentially change in the middle of
+ // executing the sorting algorithm and can throw exceptions
+ pendingFileDescriptors.add(FdSignalPair(fd, signalTime))
+ if (pendingFileDescriptors.size > MAX_FD) {
+ closePendingFileDescriptors()
+ }
}
} catch (formatException: NumberFormatException) {
Log.w(TAG, "Unable to parse fd value from name ${file.name}")
@@ -147,8 +177,10 @@
/**
* Delta in which if a fence has signalled it should be removed
*/
- const val SIGNAL_TIME_DELTA_MILLIS = 1000
+ const val SIGNAL_TIME_DELTA_MILLIS = 3000
const val MONITOR_DELAY = 1000L
+
+ const val MAX_FD = 100
}
}
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ExerciseUpdateListenerStub.kt b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ExerciseUpdateListenerStub.kt
index 86832b4..333d888 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ExerciseUpdateListenerStub.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ExerciseUpdateListenerStub.kt
@@ -82,7 +82,8 @@
/**
* A class that stores unique active instances of [ExerciseUpdateCallback] to ensure same binder
- * object is passed by framework to service side of the IPC.
+ * object is passed by framework to service side of the IPC. This is required because the same
+ * stub object that is set as the listener needs to be used to clear it.
*/
public class ExerciseUpdateListenerCache private constructor() {
private val listenerLock = Any()
@@ -91,15 +92,20 @@
private val listeners: MutableMap<ExerciseUpdateCallback, ExerciseUpdateListenerStub> =
HashMap()
- public fun getOrCreate(
+ public fun create(
listener: ExerciseUpdateCallback,
executor: Executor,
requestedDataTypesProvider: () -> Set<DataType<*, *>>
): ExerciseUpdateListenerStub {
synchronized(listenerLock) {
- return listeners.getOrPut(listener) {
- ExerciseUpdateListenerStub(listener, executor, requestedDataTypesProvider)
- }
+ // Each client can only have one listener at a time, if a new
+ // listener is being registered we should clear out the old stub.
+ // It's okay if we end up re-registering an equivalent stub.
+ listeners.clear()
+ val stub = ExerciseUpdateListenerStub(
+ listener, executor, requestedDataTypesProvider)
+ listeners.put(listener, stub)
+ return stub
}
}
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/impl/PassiveListenerCallbackStub.kt b/health/health-services-client/src/main/java/androidx/health/services/client/impl/PassiveListenerCallbackStub.kt
index 6042029..fb6b62b 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/impl/PassiveListenerCallbackStub.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/impl/PassiveListenerCallbackStub.kt
@@ -72,30 +72,35 @@
}
/**
- * Its important to use the same stub for registration and un-registration, to ensure same
- * binder object is passed by framework to service side of the IPC.
+ * Clients can only have one {@link PassiveListenerCallbackStub} registered at a time. Hold onto
+ * the last one that is registered.
+ *
+ * Note: For PassiveListenerCallback, the {@link ListenerKey} held in the stub is the important
+ * bit that is used, not the stub object itself.
*/
internal class PassiveListenerCallbackCache private constructor() {
private val listenerLock = Any()
@GuardedBy("listenerLock")
- private val listeners: MutableMap<String, PassiveListenerCallbackStub> = HashMap()
+ private var listener: PassiveListenerCallbackStub? = null
- public fun getOrCreate(
+ public fun create(
packageName: String,
executor: Executor,
callback: PassiveListenerCallback
): PassiveListenerCallbackStub {
synchronized(listenerLock) {
- return listeners.getOrPut(packageName) {
- PassiveListenerCallbackStub(packageName, executor, callback)
- }
+ val stub = PassiveListenerCallbackStub(packageName, executor, callback)
+ listener = stub
+ return stub
}
}
- public fun remove(packageName: String): PassiveListenerCallbackStub? {
+ public fun clear(): PassiveListenerCallbackStub? {
synchronized(listenerLock) {
- return listeners.remove(packageName)
+ val prev: PassiveListenerCallbackStub? = listener
+ listener = null
+ return prev
}
}
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt
index 3cd2656..0039740 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedExerciseClient.kt
@@ -144,7 +144,7 @@
callback: ExerciseUpdateCallback
) {
val listenerStub =
- ExerciseUpdateListenerStub.ExerciseUpdateListenerCache.INSTANCE.getOrCreate(
+ ExerciseUpdateListenerStub.ExerciseUpdateListenerCache.INSTANCE.create(
callback,
executor,
requestedDataTypesProvider = {
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClient.kt b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClient.kt
index 606b00e..430153b 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClient.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClient.kt
@@ -115,7 +115,7 @@
return
}
val callbackStub =
- PassiveListenerCallbackCache.INSTANCE.getOrCreate(packageName, executor, callback)
+ PassiveListenerCallbackCache.INSTANCE.create(packageName, executor, callback)
val future =
registerListener(callbackStub.listenerKey) { service, result: SettableFuture<Void?> ->
service.registerPassiveListenerCallback(
@@ -148,19 +148,13 @@
)
}
+ @Suppress("UNCHECKED_CAST")
override fun clearPassiveListenerCallbackAsync(): ListenableFuture<Void> {
- val callbackStub = PassiveListenerCallbackCache.INSTANCE.remove(packageName)
- if (callbackStub != null) {
- return unregisterListener(callbackStub.listenerKey) { service, resultFuture ->
- service.unregisterPassiveListenerCallback(packageName, StatusCallback(resultFuture))
- }
+ val callbackStub = PassiveListenerCallbackCache.INSTANCE.clear()
+ ?: return Futures.immediateFuture(null) as ListenableFuture<Void>
+ return unregisterListener(callbackStub.listenerKey) { service, resultFuture ->
+ service.unregisterPassiveListenerCallback(packageName, StatusCallback(resultFuture))
}
- return executeWithVersionCheck(
- { service, resultFuture ->
- service.unregisterPassiveListenerCallback(packageName, StatusCallback(resultFuture))
- },
- /* minApiVersion= */ 4
- )
}
override fun flushAsync(): ListenableFuture<Void> {
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
index 5a483e59..118b661 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
@@ -93,7 +93,7 @@
}
@Test
- fun registeredCallbackShouldBeInvoked() {
+ fun setUpdateCallback_registeredCallbackShouldBeInvoked() {
client.setUpdateCallback(callback)
shadowOf(getMainLooper()).idle()
@@ -102,7 +102,7 @@
}
@Test
- fun registrationFailedCallbackShouldBeInvoked() {
+ fun setUpdateCallback_registrationFailedCallbackShouldBeInvoked() {
fakeService.statusCallbackAction = { it!!.onFailure("Terrible failure!") }
client.setUpdateCallback(callback)
@@ -114,6 +114,31 @@
}
@Test
+ fun setUpdateCallback_secondCallbackReplacesFirst() {
+ client.setUpdateCallback(callback)
+ shadowOf(getMainLooper()).idle()
+ val callback2 = FakeExerciseUpdateCallback()
+ client.setUpdateCallback(callback2)
+ shadowOf(getMainLooper()).idle()
+
+ val resultFuture = client.clearUpdateCallbackAsync(callback)
+ shadowOf(getMainLooper()).idle()
+ resultFuture.get()
+ val resultFuture2 = client.clearUpdateCallbackAsync(callback2)
+ shadowOf(getMainLooper()).idle()
+ resultFuture2.get()
+
+ // Two registrations but only one clear request is sent to the
+ // FakeService since the previous listener was evicted and doesn't need
+ // to be cleared.
+ assertThat(fakeService.setListenerPackageNames).containsExactly(
+ "androidx.health.services.client.test",
+ "androidx.health.services.client.test")
+ assertThat(fakeService.clearListenerPackageNames).containsExactly(
+ "androidx.health.services.client.test")
+ }
+
+ @Test
fun clearUpdateCallbackAsync_callbackNotRegistered_noOp() {
val resultFuture = client.clearUpdateCallbackAsync(callback)
shadowOf(getMainLooper()).idle()
@@ -339,6 +364,8 @@
var listener: IExerciseUpdateListener? = null
var statusCallbackAction: (IStatusCallback?) -> Unit = { it!!.onSuccess() }
var exerciseConfig: ExerciseConfig? = null
+ val setListenerPackageNames = mutableListOf<String>()
+ val clearListenerPackageNames = mutableListOf<String>()
override fun getApiVersion(): Int = 12
@@ -381,20 +408,25 @@
}
override fun setUpdateListener(
- packageName: String?,
+ packageName: String,
listener: IExerciseUpdateListener?,
statusCallback: IStatusCallback?
) {
this.listener = listener
+ setListenerPackageNames += packageName
statusCallbackAction.invoke(statusCallback)
}
override fun clearUpdateListener(
- packageName: String?,
+ packageName: String,
listener: IExerciseUpdateListener?,
statusCallback: IStatusCallback?
) {
- throw NotImplementedError()
+ clearListenerPackageNames += packageName
+ if (this.listener == listener) {
+ this.listener = null
+ }
+ this.statusCallbackAction.invoke(statusCallback)
}
override fun addGoalToActiveExercise(
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClientTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClientTest.kt
index c56d440e..2c6a3bc 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClientTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedPassiveMonitoringClientTest.kt
@@ -144,7 +144,7 @@
}
@Test
- fun registersPassiveListenerCallback() {
+ fun setPassiveListenerCallback_registersCallback() {
val config = PassiveListenerConfig(
dataTypes = setOf(STEPS_DAILY),
shouldUserActivityInfoBeRequested = true,
@@ -165,7 +165,7 @@
}
@Test
- fun registersPassiveListenerCallback_fail() {
+ fun setPassiveListenerCallback_fail() {
val config = PassiveListenerConfig(
dataTypes = setOf(CALORIES_DAILY),
shouldUserActivityInfoBeRequested = true,
@@ -187,6 +187,31 @@
}
@Test
+ fun setPassiveListenerCallback_multipleCallbacksRegistered() {
+ val config = PassiveListenerConfig(
+ dataTypes = setOf(STEPS_DAILY),
+ shouldUserActivityInfoBeRequested = true,
+ dailyGoals = setOf(),
+ healthEventTypes = setOf()
+ )
+ val callback = FakeCallback()
+ client.setPassiveListenerCallback(config, callback)
+ shadowOf(Looper.getMainLooper()).idle()
+
+ val callback2 = FakeCallback()
+ client.setPassiveListenerCallback(config, callback2)
+ shadowOf(Looper.getMainLooper()).idle()
+
+ assertThat(fakeService.registerCallbackRequests).hasSize(2)
+ assertThat(callback.onRegisteredCalls).isEqualTo(1)
+ assertThat(callback2.onRegisteredCalls).isEqualTo(1)
+ assertThat(fakeService.registeredCallbacks).hasSize(2)
+ // Stub is not reused.
+ assertThat(fakeService.registeredCallbacks[0]).isNotSameInstanceAs(
+ fakeService.registeredCallbacks[1]);
+ }
+
+ @Test
fun callbackReceivesDataPointsAndUserActivityInfo() {
shadowOf(Looper.getMainLooper()).idle() // ?????
val config = PassiveListenerConfig(
@@ -326,6 +351,37 @@
assertThat(callback.onPermissionLostCalls).isEqualTo(1)
}
+ @Test
+ fun clearPassiveListenerCallbackAsync_nothingRegistered_noOp() {
+ // Return value of future.get() is not used, but verifying no exceptions are thrown.
+ client.clearPassiveListenerCallbackAsync().get()
+ shadowOf(Looper.getMainLooper()).idle()
+
+ assertThat(fakeService.unregisterCallbackPackageNames).isEmpty()
+ }
+
+ @Test
+ fun clearPassiveListenerCallbackAsync_callbackRegistered_sendsRequest() {
+ val config = PassiveListenerConfig(
+ dataTypes = setOf(STEPS_DAILY),
+ shouldUserActivityInfoBeRequested = true,
+ dailyGoals = setOf(),
+ healthEventTypes = setOf()
+ )
+ val callback = FakeCallback()
+ client.setPassiveListenerCallback(config, callback)
+ shadowOf(Looper.getMainLooper()).idle()
+
+ // Return value of future.get() is not used, but verifying no exceptions are thrown.
+ val resultFuture = client.clearPassiveListenerCallbackAsync()
+ shadowOf(Looper.getMainLooper()).idle()
+ resultFuture.get()
+
+ assertThat(fakeService.unregisterCallbackPackageNames).hasSize(1)
+ assertThat(fakeService.unregisterCallbackPackageNames[0]).isEqualTo(
+ "androidx.health.services.client.test")
+ }
+
class FakeListenerService : PassiveListenerService()
internal class FakeCallback : PassiveListenerCallback {
diff --git a/libraryversions.toml b/libraryversions.toml
index 5d08392..702a656 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -97,7 +97,7 @@
LINT = "1.0.0-alpha01"
LOADER = "1.2.0-alpha01"
MEDIA = "1.7.0-rc01"
-MEDIAROUTER = "1.7.0-alpha02"
+MEDIAROUTER = "1.7.0-beta01"
METRICS = "1.0.0-beta02"
NAVIGATION = "2.8.0-alpha03"
PAGING = "3.3.0-alpha03"
@@ -202,6 +202,7 @@
COMPOSE_FOUNDATION = { group = "androidx.compose.foundation", atomicGroupVersion = "versions.COMPOSE" }
COMPOSE_MATERIAL = { group = "androidx.compose.material", atomicGroupVersion = "versions.COMPOSE" }
COMPOSE_MATERIAL3 = { group = "androidx.compose.material3", atomicGroupVersion = "versions.COMPOSE_MATERIAL3" }
+COMPOSE_MATERIAL3_ADAPTIVE = { group = "androidx.compose.material3.adaptive", atomicGroupVersion = "versions.COMPOSE_MATERIAL3_ADAPTIVE" }
COMPOSE_RUNTIME = { group = "androidx.compose.runtime", atomicGroupVersion = "versions.COMPOSE" }
COMPOSE_RUNTIME_TRACING = { group = "androidx.compose.runtime", atomicGroupVersion = "versions.COMPOSE_RUNTIME_TRACING", overrideInclude = [ ":compose:runtime:runtime-tracing" ] }
COMPOSE_UI = { group = "androidx.compose.ui", atomicGroupVersion = "versions.COMPOSE" }
diff --git a/lint/lint-gradle/src/main/java/androidx/lint/gradle/GradleIssueRegistry.kt b/lint/lint-gradle/src/main/java/androidx/lint/gradle/GradleIssueRegistry.kt
index 7d3cfd3..bdc7136 100644
--- a/lint/lint-gradle/src/main/java/androidx/lint/gradle/GradleIssueRegistry.kt
+++ b/lint/lint-gradle/src/main/java/androidx/lint/gradle/GradleIssueRegistry.kt
@@ -33,7 +33,7 @@
override val vendor = Vendor(
// TODO: Update component (or the issue template)
feedbackUrl = "https://issuetracker.google.com/issues/new?component=1147525",
- identifier = "androidx.gradle-lint:gradle-lint-checks",
+ identifier = "androidx.lint:lint-gradle",
vendorName = "Android Open Source Project",
)
}
diff --git a/mediarouter/mediarouter-testing/api/1.7.0-beta01.txt b/mediarouter/mediarouter-testing/api/1.7.0-beta01.txt
new file mode 100644
index 0000000..14e1df6
--- /dev/null
+++ b/mediarouter/mediarouter-testing/api/1.7.0-beta01.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.mediarouter.testing {
+
+ public class MediaRouterTestHelper {
+ method @MainThread public static void resetMediaRouter();
+ }
+
+}
+
diff --git a/compose/material3/material3-adaptive/api/res-current.txt b/mediarouter/mediarouter-testing/api/res-1.7.0-beta01.txt
similarity index 100%
copy from compose/material3/material3-adaptive/api/res-current.txt
copy to mediarouter/mediarouter-testing/api/res-1.7.0-beta01.txt
diff --git a/mediarouter/mediarouter-testing/api/restricted_1.7.0-beta01.txt b/mediarouter/mediarouter-testing/api/restricted_1.7.0-beta01.txt
new file mode 100644
index 0000000..14e1df6
--- /dev/null
+++ b/mediarouter/mediarouter-testing/api/restricted_1.7.0-beta01.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.mediarouter.testing {
+
+ public class MediaRouterTestHelper {
+ method @MainThread public static void resetMediaRouter();
+ }
+
+}
+
diff --git a/mediarouter/mediarouter/api/1.7.0-beta01.txt b/mediarouter/mediarouter/api/1.7.0-beta01.txt
new file mode 100644
index 0000000..e67bdb6
--- /dev/null
+++ b/mediarouter/mediarouter/api/1.7.0-beta01.txt
@@ -0,0 +1,638 @@
+// Signature format: 4.0
+package androidx.mediarouter.app {
+
+ public class MediaRouteActionProvider extends androidx.core.view.ActionProvider {
+ ctor public MediaRouteActionProvider(android.content.Context);
+ method @Deprecated public void enableDynamicGroup();
+ method public androidx.mediarouter.app.MediaRouteDialogFactory getDialogFactory();
+ method public androidx.mediarouter.app.MediaRouteButton? getMediaRouteButton();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public android.view.View onCreateActionView();
+ method public androidx.mediarouter.app.MediaRouteButton onCreateMediaRouteButton();
+ method @Deprecated public void setAlwaysVisible(boolean);
+ method public void setDialogFactory(androidx.mediarouter.app.MediaRouteDialogFactory);
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteButton extends android.view.View {
+ ctor public MediaRouteButton(android.content.Context);
+ ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?);
+ ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?, int);
+ method @Deprecated public void enableDynamicGroup();
+ method public androidx.mediarouter.app.MediaRouteDialogFactory getDialogFactory();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method @Deprecated public void setAlwaysVisible(boolean);
+ method public void setDialogFactory(androidx.mediarouter.app.MediaRouteDialogFactory);
+ method public void setRemoteIndicatorDrawable(android.graphics.drawable.Drawable?);
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ method public boolean showDialog();
+ }
+
+ public class MediaRouteChooserDialog extends androidx.appcompat.app.AppCompatDialog {
+ ctor public MediaRouteChooserDialog(android.content.Context);
+ ctor public MediaRouteChooserDialog(android.content.Context, int);
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public boolean onFilterRoute(androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onFilterRoutes(java.util.List<androidx.mediarouter.media.MediaRouter.RouteInfo!>);
+ method public void refreshRoutes();
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteChooserDialogFragment extends androidx.fragment.app.DialogFragment {
+ ctor public MediaRouteChooserDialogFragment();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public androidx.mediarouter.app.MediaRouteChooserDialog onCreateChooserDialog(android.content.Context, android.os.Bundle?);
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteControllerDialog extends androidx.appcompat.app.AlertDialog {
+ ctor public MediaRouteControllerDialog(android.content.Context);
+ ctor public MediaRouteControllerDialog(android.content.Context, int);
+ method public android.view.View? getMediaControlView();
+ method public android.support.v4.media.session.MediaSessionCompat.Token? getMediaSession();
+ method public androidx.mediarouter.media.MediaRouter.RouteInfo getRoute();
+ method public boolean isVolumeControlEnabled();
+ method public android.view.View? onCreateMediaControlView(android.os.Bundle?);
+ method public void setVolumeControlEnabled(boolean);
+ }
+
+ public class MediaRouteControllerDialogFragment extends androidx.fragment.app.DialogFragment {
+ ctor public MediaRouteControllerDialogFragment();
+ method public androidx.mediarouter.app.MediaRouteControllerDialog onCreateControllerDialog(android.content.Context, android.os.Bundle?);
+ }
+
+ public class MediaRouteDialogFactory {
+ ctor public MediaRouteDialogFactory();
+ method public static androidx.mediarouter.app.MediaRouteDialogFactory getDefault();
+ method public androidx.mediarouter.app.MediaRouteChooserDialogFragment onCreateChooserDialogFragment();
+ method public androidx.mediarouter.app.MediaRouteControllerDialogFragment onCreateControllerDialogFragment();
+ }
+
+ public class MediaRouteDiscoveryFragment extends androidx.fragment.app.Fragment {
+ ctor public MediaRouteDiscoveryFragment();
+ method public androidx.mediarouter.media.MediaRouter getMediaRouter();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public androidx.mediarouter.media.MediaRouter.Callback? onCreateCallback();
+ method public int onPrepareCallbackFlags();
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public final class SystemOutputSwitcherDialogController {
+ method public static boolean showDialog(android.content.Context);
+ }
+
+}
+
+package androidx.mediarouter.media {
+
+ public final class MediaControlIntent {
+ field public static final String ACTION_END_SESSION = "android.media.intent.action.END_SESSION";
+ field public static final String ACTION_ENQUEUE = "android.media.intent.action.ENQUEUE";
+ field public static final String ACTION_GET_SESSION_STATUS = "android.media.intent.action.GET_SESSION_STATUS";
+ field public static final String ACTION_GET_STATUS = "android.media.intent.action.GET_STATUS";
+ field public static final String ACTION_PAUSE = "android.media.intent.action.PAUSE";
+ field public static final String ACTION_PLAY = "android.media.intent.action.PLAY";
+ field public static final String ACTION_REMOVE = "android.media.intent.action.REMOVE";
+ field public static final String ACTION_RESUME = "android.media.intent.action.RESUME";
+ field public static final String ACTION_SEEK = "android.media.intent.action.SEEK";
+ field public static final String ACTION_SEND_MESSAGE = "android.media.intent.action.SEND_MESSAGE";
+ field public static final String ACTION_START_SESSION = "android.media.intent.action.START_SESSION";
+ field public static final String ACTION_STOP = "android.media.intent.action.STOP";
+ field public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+ field public static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+ field public static final String CATEGORY_REMOTE_PLAYBACK = "android.media.intent.category.REMOTE_PLAYBACK";
+ field public static final int ERROR_INVALID_ITEM_ID = 3; // 0x3
+ field public static final int ERROR_INVALID_SESSION_ID = 2; // 0x2
+ field public static final int ERROR_UNKNOWN = 0; // 0x0
+ field public static final int ERROR_UNSUPPORTED_OPERATION = 1; // 0x1
+ field public static final String EXTRA_ERROR_CODE = "android.media.intent.extra.ERROR_CODE";
+ field public static final String EXTRA_ITEM_CONTENT_POSITION = "android.media.intent.extra.ITEM_POSITION";
+ field public static final String EXTRA_ITEM_HTTP_HEADERS = "android.media.intent.extra.HTTP_HEADERS";
+ field public static final String EXTRA_ITEM_ID = "android.media.intent.extra.ITEM_ID";
+ field public static final String EXTRA_ITEM_METADATA = "android.media.intent.extra.ITEM_METADATA";
+ field public static final String EXTRA_ITEM_STATUS = "android.media.intent.extra.ITEM_STATUS";
+ field public static final String EXTRA_ITEM_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.ITEM_STATUS_UPDATE_RECEIVER";
+ field public static final String EXTRA_MESSAGE = "android.media.intent.extra.MESSAGE";
+ field public static final String EXTRA_MESSAGE_RECEIVER = "android.media.intent.extra.MESSAGE_RECEIVER";
+ field public static final String EXTRA_SESSION_ID = "android.media.intent.extra.SESSION_ID";
+ field public static final String EXTRA_SESSION_STATUS = "android.media.intent.extra.SESSION_STATUS";
+ field public static final String EXTRA_SESSION_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.SESSION_STATUS_UPDATE_RECEIVER";
+ }
+
+ public final class MediaItemMetadata {
+ field public static final String KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+ field public static final String KEY_ALBUM_TITLE = "android.media.metadata.ALBUM_TITLE";
+ field public static final String KEY_ARTIST = "android.media.metadata.ARTIST";
+ field public static final String KEY_ARTWORK_URI = "android.media.metadata.ARTWORK_URI";
+ field public static final String KEY_AUTHOR = "android.media.metadata.AUTHOR";
+ field public static final String KEY_COMPOSER = "android.media.metadata.COMPOSER";
+ field public static final String KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+ field public static final String KEY_DURATION = "android.media.metadata.DURATION";
+ field public static final String KEY_TITLE = "android.media.metadata.TITLE";
+ field public static final String KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+ field public static final String KEY_YEAR = "android.media.metadata.YEAR";
+ }
+
+ public final class MediaItemStatus {
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaItemStatus? fromBundle(android.os.Bundle?);
+ method public long getContentDuration();
+ method public long getContentPosition();
+ method public android.os.Bundle? getExtras();
+ method public int getPlaybackState();
+ method public long getTimestamp();
+ field public static final String EXTRA_HTTP_RESPONSE_HEADERS = "android.media.status.extra.HTTP_RESPONSE_HEADERS";
+ field public static final String EXTRA_HTTP_STATUS_CODE = "android.media.status.extra.HTTP_STATUS_CODE";
+ field public static final int PLAYBACK_STATE_BUFFERING = 3; // 0x3
+ field public static final int PLAYBACK_STATE_CANCELED = 5; // 0x5
+ field public static final int PLAYBACK_STATE_ERROR = 7; // 0x7
+ field public static final int PLAYBACK_STATE_FINISHED = 4; // 0x4
+ field public static final int PLAYBACK_STATE_INVALIDATED = 6; // 0x6
+ field public static final int PLAYBACK_STATE_PAUSED = 2; // 0x2
+ field public static final int PLAYBACK_STATE_PENDING = 0; // 0x0
+ field public static final int PLAYBACK_STATE_PLAYING = 1; // 0x1
+ }
+
+ public static final class MediaItemStatus.Builder {
+ ctor public MediaItemStatus.Builder(androidx.mediarouter.media.MediaItemStatus);
+ ctor public MediaItemStatus.Builder(int);
+ method public androidx.mediarouter.media.MediaItemStatus build();
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setContentDuration(long);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setContentPosition(long);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setExtras(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setPlaybackState(int);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setTimestamp(long);
+ }
+
+ public final class MediaRouteDescriptor {
+ method public android.os.Bundle asBundle();
+ method public boolean canDisconnectAndKeepPlaying();
+ method public static androidx.mediarouter.media.MediaRouteDescriptor? fromBundle(android.os.Bundle?);
+ method public java.util.Set<java.lang.String!> getAllowedPackages();
+ method public int getConnectionState();
+ method public java.util.List<android.content.IntentFilter!> getControlFilters();
+ method public java.util.Set<java.lang.String!> getDeduplicationIds();
+ method public String? getDescription();
+ method public int getDeviceType();
+ method public android.os.Bundle? getExtras();
+ method public android.net.Uri? getIconUri();
+ method public String getId();
+ method public String getName();
+ method public int getPlaybackStream();
+ method public int getPlaybackType();
+ method public int getPresentationDisplayId();
+ method public android.content.IntentSender? getSettingsActivity();
+ method public int getVolume();
+ method public int getVolumeHandling();
+ method public int getVolumeMax();
+ method @Deprecated public boolean isConnecting();
+ method public boolean isDynamicGroupRoute();
+ method public boolean isEnabled();
+ method public boolean isSystemRoute();
+ method public boolean isValid();
+ method public boolean isVisibilityPublic();
+ }
+
+ public static final class MediaRouteDescriptor.Builder {
+ ctor public MediaRouteDescriptor.Builder(androidx.mediarouter.media.MediaRouteDescriptor);
+ ctor public MediaRouteDescriptor.Builder(String, String);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder addControlFilter(android.content.IntentFilter);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder addControlFilters(java.util.Collection<android.content.IntentFilter!>);
+ method public androidx.mediarouter.media.MediaRouteDescriptor build();
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder clearControlFilters();
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setCanDisconnect(boolean);
+ method @Deprecated public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnecting(boolean);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnectionState(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeduplicationIds(java.util.Set<java.lang.String!>);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDescription(String?);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeviceType(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setEnabled(boolean);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setExtras(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setIconUri(android.net.Uri);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setId(String);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setIsDynamicGroupRoute(boolean);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setName(String);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPlaybackStream(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPlaybackType(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPresentationDisplayId(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setSettingsActivity(android.content.IntentSender?);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityPublic();
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityRestricted(java.util.Set<java.lang.String!>);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolume(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeHandling(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeMax(int);
+ }
+
+ public final class MediaRouteDiscoveryRequest {
+ ctor public MediaRouteDiscoveryRequest(androidx.mediarouter.media.MediaRouteSelector, boolean);
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaRouteDiscoveryRequest? fromBundle(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaRouteSelector getSelector();
+ method public boolean isActiveScan();
+ method public boolean isValid();
+ }
+
+ public abstract class MediaRouteProvider {
+ ctor public MediaRouteProvider(android.content.Context);
+ method public final android.content.Context getContext();
+ method public final androidx.mediarouter.media.MediaRouteProviderDescriptor? getDescriptor();
+ method public final androidx.mediarouter.media.MediaRouteDiscoveryRequest? getDiscoveryRequest();
+ method public final android.os.Handler getHandler();
+ method public final androidx.mediarouter.media.MediaRouteProvider.ProviderMetadata getMetadata();
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController? onCreateDynamicGroupRouteController(String);
+ method public androidx.mediarouter.media.MediaRouteProvider.RouteController? onCreateRouteController(String);
+ method public void onDiscoveryRequestChanged(androidx.mediarouter.media.MediaRouteDiscoveryRequest?);
+ method public final void setCallback(androidx.mediarouter.media.MediaRouteProvider.Callback?);
+ method public final void setDescriptor(androidx.mediarouter.media.MediaRouteProviderDescriptor?);
+ method public final void setDiscoveryRequest(androidx.mediarouter.media.MediaRouteDiscoveryRequest?);
+ }
+
+ public abstract static class MediaRouteProvider.Callback {
+ ctor public MediaRouteProvider.Callback();
+ method public void onDescriptorChanged(androidx.mediarouter.media.MediaRouteProvider, androidx.mediarouter.media.MediaRouteProviderDescriptor?);
+ }
+
+ public abstract static class MediaRouteProvider.DynamicGroupRouteController extends androidx.mediarouter.media.MediaRouteProvider.RouteController {
+ ctor public MediaRouteProvider.DynamicGroupRouteController();
+ method public String? getGroupableSelectionTitle();
+ method public String? getTransferableSectionTitle();
+ method public final void notifyDynamicRoutesChanged(androidx.mediarouter.media.MediaRouteDescriptor, java.util.Collection<androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor!>);
+ method @Deprecated public final void notifyDynamicRoutesChanged(java.util.Collection<androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor!>);
+ method public abstract void onAddMemberRoute(String);
+ method public abstract void onRemoveMemberRoute(String);
+ method public abstract void onUpdateMemberRoutes(java.util.List<java.lang.String!>?);
+ }
+
+ public static final class MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor {
+ method public androidx.mediarouter.media.MediaRouteDescriptor getRouteDescriptor();
+ method public int getSelectionState();
+ method public boolean isGroupable();
+ method public boolean isTransferable();
+ method public boolean isUnselectable();
+ field public static final int SELECTED = 3; // 0x3
+ field public static final int SELECTING = 2; // 0x2
+ field public static final int UNSELECTED = 1; // 0x1
+ field public static final int UNSELECTING = 0; // 0x0
+ }
+
+ public static final class MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder {
+ ctor public MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder(androidx.mediarouter.media.MediaRouteDescriptor);
+ ctor public MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder(androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor build();
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setIsGroupable(boolean);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setIsTransferable(boolean);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setIsUnselectable(boolean);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setSelectionState(int);
+ }
+
+ public static final class MediaRouteProvider.ProviderMetadata {
+ method public android.content.ComponentName getComponentName();
+ method public String getPackageName();
+ }
+
+ public abstract static class MediaRouteProvider.RouteController {
+ ctor public MediaRouteProvider.RouteController();
+ method public boolean onControlRequest(android.content.Intent, androidx.mediarouter.media.MediaRouter.ControlRequestCallback?);
+ method public void onRelease();
+ method public void onSelect();
+ method public void onSetVolume(int);
+ method @Deprecated public void onUnselect();
+ method public void onUnselect(int);
+ method public void onUpdateVolume(int);
+ }
+
+ public final class MediaRouteProviderDescriptor {
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaRouteProviderDescriptor? fromBundle(android.os.Bundle?);
+ method public java.util.List<androidx.mediarouter.media.MediaRouteDescriptor!> getRoutes();
+ method public boolean isValid();
+ method public boolean supportsDynamicGroupRoute();
+ }
+
+ public static final class MediaRouteProviderDescriptor.Builder {
+ ctor public MediaRouteProviderDescriptor.Builder();
+ ctor public MediaRouteProviderDescriptor.Builder(androidx.mediarouter.media.MediaRouteProviderDescriptor);
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder addRoute(androidx.mediarouter.media.MediaRouteDescriptor);
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder addRoutes(java.util.Collection<androidx.mediarouter.media.MediaRouteDescriptor!>);
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor build();
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder setSupportsDynamicGroupRoute(boolean);
+ }
+
+ public abstract class MediaRouteProviderService extends android.app.Service {
+ ctor public MediaRouteProviderService();
+ method public androidx.mediarouter.media.MediaRouteProvider? getMediaRouteProvider();
+ method public android.os.IBinder? onBind(android.content.Intent);
+ method public abstract androidx.mediarouter.media.MediaRouteProvider? onCreateMediaRouteProvider();
+ field public static final String SERVICE_INTERFACE = "android.media.MediaRouteProviderService";
+ }
+
+ public final class MediaRouteSelector {
+ method public android.os.Bundle asBundle();
+ method public boolean contains(androidx.mediarouter.media.MediaRouteSelector);
+ method public static androidx.mediarouter.media.MediaRouteSelector? fromBundle(android.os.Bundle?);
+ method public java.util.List<java.lang.String!> getControlCategories();
+ method public boolean hasControlCategory(String?);
+ method public boolean isEmpty();
+ method public boolean isValid();
+ method public boolean matchesControlFilters(java.util.List<android.content.IntentFilter!>?);
+ field public static final androidx.mediarouter.media.MediaRouteSelector! EMPTY;
+ }
+
+ public static final class MediaRouteSelector.Builder {
+ ctor public MediaRouteSelector.Builder();
+ ctor public MediaRouteSelector.Builder(androidx.mediarouter.media.MediaRouteSelector);
+ method public androidx.mediarouter.media.MediaRouteSelector.Builder addControlCategories(java.util.Collection<java.lang.String!>);
+ method public androidx.mediarouter.media.MediaRouteSelector.Builder addControlCategory(String);
+ method public androidx.mediarouter.media.MediaRouteSelector.Builder addSelector(androidx.mediarouter.media.MediaRouteSelector);
+ method public androidx.mediarouter.media.MediaRouteSelector build();
+ }
+
+ public final class MediaRouter {
+ method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback);
+ method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback, int);
+ method @MainThread public void addProvider(androidx.mediarouter.media.MediaRouteProvider);
+ method @Deprecated @MainThread public void addRemoteControlClient(Object);
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo? getBluetoothRoute();
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo getDefaultRoute();
+ method @MainThread public static androidx.mediarouter.media.MediaRouter getInstance(android.content.Context);
+ method public android.support.v4.media.session.MediaSessionCompat.Token? getMediaSessionToken();
+ method @MainThread public java.util.List<androidx.mediarouter.media.MediaRouter.ProviderInfo!> getProviders();
+ method @MainThread public androidx.mediarouter.media.MediaRouterParams? getRouterParams();
+ method @MainThread public java.util.List<androidx.mediarouter.media.MediaRouter.RouteInfo!> getRoutes();
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo getSelectedRoute();
+ method @MainThread public boolean isRouteAvailable(androidx.mediarouter.media.MediaRouteSelector, int);
+ method @MainThread public void removeCallback(androidx.mediarouter.media.MediaRouter.Callback);
+ method @MainThread public void removeProvider(androidx.mediarouter.media.MediaRouteProvider);
+ method @Deprecated @MainThread public void removeRemoteControlClient(Object);
+ method @MainThread public void selectRoute(androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method @MainThread public void setMediaSession(Object?);
+ method @MainThread public void setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat?);
+ method @MainThread public void setOnPrepareTransferListener(androidx.mediarouter.media.MediaRouter.OnPrepareTransferListener?);
+ method @MainThread public void setRouteListingPreference(androidx.mediarouter.media.RouteListingPreference?);
+ method @MainThread public void setRouterParams(androidx.mediarouter.media.MediaRouterParams?);
+ method @MainThread public void unselect(int);
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo updateSelectedRoute(androidx.mediarouter.media.MediaRouteSelector);
+ field public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1; // 0x1
+ field public static final int AVAILABILITY_FLAG_REQUIRE_MATCH = 2; // 0x2
+ field public static final int CALLBACK_FLAG_FORCE_DISCOVERY = 8; // 0x8
+ field public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1; // 0x1
+ field public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 4; // 0x4
+ field public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 2; // 0x2
+ field public static final int UNSELECT_REASON_DISCONNECTED = 1; // 0x1
+ field public static final int UNSELECT_REASON_ROUTE_CHANGED = 3; // 0x3
+ field public static final int UNSELECT_REASON_STOPPED = 2; // 0x2
+ field public static final int UNSELECT_REASON_UNKNOWN = 0; // 0x0
+ }
+
+ public abstract static class MediaRouter.Callback {
+ ctor public MediaRouter.Callback();
+ method public void onProviderAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo);
+ method public void onProviderChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo);
+ method public void onProviderRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo);
+ method public void onRouteAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRoutePresentationDisplayChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method @Deprecated public void onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int);
+ method public void onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method @Deprecated public void onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int);
+ method public void onRouteVolumeChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ }
+
+ public abstract static class MediaRouter.ControlRequestCallback {
+ ctor public MediaRouter.ControlRequestCallback();
+ method public void onError(String?, android.os.Bundle?);
+ method public void onResult(android.os.Bundle?);
+ }
+
+ public static interface MediaRouter.OnPrepareTransferListener {
+ method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!>? onPrepareTransfer(androidx.mediarouter.media.MediaRouter.RouteInfo, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ }
+
+ public static final class MediaRouter.ProviderInfo {
+ method public android.content.ComponentName getComponentName();
+ method public String getPackageName();
+ method @MainThread public androidx.mediarouter.media.MediaRouteProvider getProviderInstance();
+ method @MainThread public java.util.List<androidx.mediarouter.media.MediaRouter.RouteInfo!> getRoutes();
+ }
+
+ public static class MediaRouter.RouteInfo {
+ method public boolean canDisconnect();
+ method public int getConnectionState();
+ method public java.util.List<android.content.IntentFilter!> getControlFilters();
+ method public String? getDescription();
+ method public int getDeviceType();
+ method public android.os.Bundle? getExtras();
+ method public android.net.Uri? getIconUri();
+ method public String getId();
+ method public String getName();
+ method public int getPlaybackStream();
+ method public int getPlaybackType();
+ method @MainThread public android.view.Display? getPresentationDisplay();
+ method public androidx.mediarouter.media.MediaRouter.ProviderInfo getProvider();
+ method public android.content.IntentSender? getSettingsIntent();
+ method public int getVolume();
+ method public int getVolumeHandling();
+ method public int getVolumeMax();
+ method @MainThread public boolean isBluetooth();
+ method @Deprecated public boolean isConnecting();
+ method @MainThread public boolean isDefault();
+ method public boolean isDeviceSpeaker();
+ method public boolean isEnabled();
+ method @MainThread public boolean isSelected();
+ method public boolean isSystemRoute();
+ method @MainThread public boolean matchesSelector(androidx.mediarouter.media.MediaRouteSelector);
+ method @MainThread public void requestSetVolume(int);
+ method @MainThread public void requestUpdateVolume(int);
+ method @MainThread public void select();
+ method @MainThread public void sendControlRequest(android.content.Intent, androidx.mediarouter.media.MediaRouter.ControlRequestCallback?);
+ method @MainThread public boolean supportsControlAction(String, String);
+ method @MainThread public boolean supportsControlCategory(String);
+ method @MainThread public boolean supportsControlRequest(android.content.Intent);
+ field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
+ field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
+ field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
+ field public static final int DEVICE_TYPE_AUDIO_VIDEO_RECEIVER = 4; // 0x4
+ field public static final int DEVICE_TYPE_BLE_HEADSET = 22; // 0x16
+ field public static final int DEVICE_TYPE_BLUETOOTH_A2DP = 3; // 0x3
+ field public static final int DEVICE_TYPE_BUILTIN_SPEAKER = 12; // 0xc
+ field public static final int DEVICE_TYPE_CAR = 9; // 0x9
+ field public static final int DEVICE_TYPE_COMPUTER = 7; // 0x7
+ field public static final int DEVICE_TYPE_DOCK = 19; // 0x13
+ field public static final int DEVICE_TYPE_GAME_CONSOLE = 8; // 0x8
+ field public static final int DEVICE_TYPE_GROUP = 1000; // 0x3e8
+ field public static final int DEVICE_TYPE_HDMI = 16; // 0x10
+ field public static final int DEVICE_TYPE_HDMI_ARC = 23; // 0x17
+ field public static final int DEVICE_TYPE_HDMI_EARC = 24; // 0x18
+ field public static final int DEVICE_TYPE_HEARING_AID = 21; // 0x15
+ field public static final int DEVICE_TYPE_REMOTE_SPEAKER = 2; // 0x2
+ field public static final int DEVICE_TYPE_SMARTPHONE = 11; // 0xb
+ field public static final int DEVICE_TYPE_SMARTWATCH = 10; // 0xa
+ field @Deprecated public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+ field public static final int DEVICE_TYPE_TABLET = 5; // 0x5
+ field public static final int DEVICE_TYPE_TABLET_DOCKED = 6; // 0x6
+ field public static final int DEVICE_TYPE_TV = 1; // 0x1
+ field public static final int DEVICE_TYPE_USB_ACCESSORY = 18; // 0x12
+ field public static final int DEVICE_TYPE_USB_DEVICE = 17; // 0x11
+ field public static final int DEVICE_TYPE_USB_HEADSET = 20; // 0x14
+ field public static final int DEVICE_TYPE_WIRED_HEADPHONES = 14; // 0xe
+ field public static final int DEVICE_TYPE_WIRED_HEADSET = 13; // 0xd
+ field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
+ field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
+ field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+ field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+ }
+
+ public class MediaRouterParams {
+ method public int getDialogType();
+ method public boolean isMediaTransferReceiverEnabled();
+ method public boolean isOutputSwitcherEnabled();
+ method public boolean isTransferToLocalEnabled();
+ field public static final int DIALOG_TYPE_DEFAULT = 1; // 0x1
+ field public static final int DIALOG_TYPE_DYNAMIC_GROUP = 2; // 0x2
+ field public static final String ENABLE_GROUP_VOLUME_UX = "androidx.mediarouter.media.MediaRouterParams.ENABLE_GROUP_VOLUME_UX";
+ }
+
+ public static final class MediaRouterParams.Builder {
+ ctor public MediaRouterParams.Builder();
+ ctor public MediaRouterParams.Builder(androidx.mediarouter.media.MediaRouterParams);
+ method public androidx.mediarouter.media.MediaRouterParams build();
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setDialogType(int);
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setMediaTransferReceiverEnabled(boolean);
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setOutputSwitcherEnabled(boolean);
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setTransferToLocalEnabled(boolean);
+ }
+
+ public final class MediaSessionStatus {
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaSessionStatus? fromBundle(android.os.Bundle?);
+ method public android.os.Bundle? getExtras();
+ method public int getSessionState();
+ method public long getTimestamp();
+ method public boolean isQueuePaused();
+ field public static final int SESSION_STATE_ACTIVE = 0; // 0x0
+ field public static final int SESSION_STATE_ENDED = 1; // 0x1
+ field public static final int SESSION_STATE_INVALIDATED = 2; // 0x2
+ }
+
+ public static final class MediaSessionStatus.Builder {
+ ctor public MediaSessionStatus.Builder(androidx.mediarouter.media.MediaSessionStatus);
+ ctor public MediaSessionStatus.Builder(int);
+ method public androidx.mediarouter.media.MediaSessionStatus build();
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setExtras(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setQueuePaused(boolean);
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setSessionState(int);
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setTimestamp(long);
+ }
+
+ public final class MediaTransferReceiver extends android.content.BroadcastReceiver {
+ ctor public MediaTransferReceiver();
+ method public void onReceive(android.content.Context, android.content.Intent);
+ }
+
+ public class RemotePlaybackClient {
+ ctor public RemotePlaybackClient(android.content.Context, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void endSession(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void enqueue(android.net.Uri, String?, android.os.Bundle?, long, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public String? getSessionId();
+ method public void getSessionStatus(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void getStatus(String, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public boolean hasSession();
+ method public boolean isMessagingSupported();
+ method public boolean isQueuingSupported();
+ method public boolean isRemotePlaybackSupported();
+ method public boolean isSessionManagementSupported();
+ method public void pause(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void play(android.net.Uri, String?, android.os.Bundle?, long, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public void release();
+ method public void remove(String, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public void resume(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void seek(String, long, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public void sendMessage(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void setOnMessageReceivedListener(androidx.mediarouter.media.RemotePlaybackClient.OnMessageReceivedListener?);
+ method public void setSessionId(String?);
+ method public void setStatusCallback(androidx.mediarouter.media.RemotePlaybackClient.StatusCallback?);
+ method public void startSession(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void stop(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ }
+
+ public abstract static class RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.ActionCallback();
+ method public void onError(String?, int, android.os.Bundle?);
+ }
+
+ public abstract static class RemotePlaybackClient.ItemActionCallback extends androidx.mediarouter.media.RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.ItemActionCallback();
+ method public void onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus?, String, androidx.mediarouter.media.MediaItemStatus);
+ }
+
+ public static interface RemotePlaybackClient.OnMessageReceivedListener {
+ method public void onMessageReceived(String, android.os.Bundle?);
+ }
+
+ public abstract static class RemotePlaybackClient.SessionActionCallback extends androidx.mediarouter.media.RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.SessionActionCallback();
+ method public void onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus?);
+ }
+
+ public abstract static class RemotePlaybackClient.StatusCallback {
+ ctor public RemotePlaybackClient.StatusCallback();
+ method public void onItemStatusChanged(android.os.Bundle?, String, androidx.mediarouter.media.MediaSessionStatus?, String, androidx.mediarouter.media.MediaItemStatus);
+ method public void onSessionChanged(String?);
+ method public void onSessionStatusChanged(android.os.Bundle?, String, androidx.mediarouter.media.MediaSessionStatus?);
+ }
+
+ public final class RouteListingPreference {
+ method public java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!> getItems();
+ method public android.content.ComponentName? getLinkedItemComponentName();
+ method public boolean isSystemOrderingEnabled();
+ field public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA";
+ field public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID";
+ }
+
+ public static final class RouteListingPreference.Builder {
+ ctor public RouteListingPreference.Builder();
+ method public androidx.mediarouter.media.RouteListingPreference build();
+ method public androidx.mediarouter.media.RouteListingPreference.Builder setItems(java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!>);
+ method public androidx.mediarouter.media.RouteListingPreference.Builder setLinkedItemComponentName(android.content.ComponentName?);
+ method public androidx.mediarouter.media.RouteListingPreference.Builder setSystemOrderingEnabled(boolean);
+ }
+
+ public static final class RouteListingPreference.Item {
+ method public CharSequence? getCustomSubtextMessage();
+ method public int getFlags();
+ method public String getRouteId();
+ method public int getSelectionBehavior();
+ method public int getSubText();
+ field public static final int FLAG_ONGOING_SESSION = 1; // 0x1
+ field public static final int FLAG_ONGOING_SESSION_MANAGED = 2; // 0x2
+ field public static final int FLAG_SUGGESTED = 4; // 0x4
+ field public static final int SELECTION_BEHAVIOR_GO_TO_APP = 2; // 0x2
+ field public static final int SELECTION_BEHAVIOR_NONE = 0; // 0x0
+ field public static final int SELECTION_BEHAVIOR_TRANSFER = 1; // 0x1
+ field public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 4; // 0x4
+ field public static final int SUBTEXT_CUSTOM = 10000; // 0x2710
+ field public static final int SUBTEXT_DEVICE_LOW_POWER = 5; // 0x5
+ field public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 3; // 0x3
+ field public static final int SUBTEXT_ERROR_UNKNOWN = 1; // 0x1
+ field public static final int SUBTEXT_NONE = 0; // 0x0
+ field public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 2; // 0x2
+ field public static final int SUBTEXT_TRACK_UNSUPPORTED = 7; // 0x7
+ field public static final int SUBTEXT_UNAUTHORIZED = 6; // 0x6
+ }
+
+ public static final class RouteListingPreference.Item.Builder {
+ ctor public RouteListingPreference.Item.Builder(String);
+ method public androidx.mediarouter.media.RouteListingPreference.Item build();
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setCustomSubtextMessage(CharSequence?);
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setFlags(int);
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSelectionBehavior(int);
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSubText(int);
+ }
+
+}
+
diff --git a/mediarouter/mediarouter/api/res-1.7.0-beta01.txt b/mediarouter/mediarouter/api/res-1.7.0-beta01.txt
new file mode 100644
index 0000000..620c3fe
--- /dev/null
+++ b/mediarouter/mediarouter/api/res-1.7.0-beta01.txt
@@ -0,0 +1,4 @@
+dimen mediarouter_chooser_list_item_padding_bottom
+dimen mediarouter_chooser_list_item_padding_end
+dimen mediarouter_chooser_list_item_padding_start
+dimen mediarouter_chooser_list_item_padding_top
diff --git a/mediarouter/mediarouter/api/restricted_1.7.0-beta01.txt b/mediarouter/mediarouter/api/restricted_1.7.0-beta01.txt
new file mode 100644
index 0000000..e67bdb6
--- /dev/null
+++ b/mediarouter/mediarouter/api/restricted_1.7.0-beta01.txt
@@ -0,0 +1,638 @@
+// Signature format: 4.0
+package androidx.mediarouter.app {
+
+ public class MediaRouteActionProvider extends androidx.core.view.ActionProvider {
+ ctor public MediaRouteActionProvider(android.content.Context);
+ method @Deprecated public void enableDynamicGroup();
+ method public androidx.mediarouter.app.MediaRouteDialogFactory getDialogFactory();
+ method public androidx.mediarouter.app.MediaRouteButton? getMediaRouteButton();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public android.view.View onCreateActionView();
+ method public androidx.mediarouter.app.MediaRouteButton onCreateMediaRouteButton();
+ method @Deprecated public void setAlwaysVisible(boolean);
+ method public void setDialogFactory(androidx.mediarouter.app.MediaRouteDialogFactory);
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteButton extends android.view.View {
+ ctor public MediaRouteButton(android.content.Context);
+ ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?);
+ ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?, int);
+ method @Deprecated public void enableDynamicGroup();
+ method public androidx.mediarouter.app.MediaRouteDialogFactory getDialogFactory();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method @Deprecated public void setAlwaysVisible(boolean);
+ method public void setDialogFactory(androidx.mediarouter.app.MediaRouteDialogFactory);
+ method public void setRemoteIndicatorDrawable(android.graphics.drawable.Drawable?);
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ method public boolean showDialog();
+ }
+
+ public class MediaRouteChooserDialog extends androidx.appcompat.app.AppCompatDialog {
+ ctor public MediaRouteChooserDialog(android.content.Context);
+ ctor public MediaRouteChooserDialog(android.content.Context, int);
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public boolean onFilterRoute(androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onFilterRoutes(java.util.List<androidx.mediarouter.media.MediaRouter.RouteInfo!>);
+ method public void refreshRoutes();
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteChooserDialogFragment extends androidx.fragment.app.DialogFragment {
+ ctor public MediaRouteChooserDialogFragment();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public androidx.mediarouter.app.MediaRouteChooserDialog onCreateChooserDialog(android.content.Context, android.os.Bundle?);
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteControllerDialog extends androidx.appcompat.app.AlertDialog {
+ ctor public MediaRouteControllerDialog(android.content.Context);
+ ctor public MediaRouteControllerDialog(android.content.Context, int);
+ method public android.view.View? getMediaControlView();
+ method public android.support.v4.media.session.MediaSessionCompat.Token? getMediaSession();
+ method public androidx.mediarouter.media.MediaRouter.RouteInfo getRoute();
+ method public boolean isVolumeControlEnabled();
+ method public android.view.View? onCreateMediaControlView(android.os.Bundle?);
+ method public void setVolumeControlEnabled(boolean);
+ }
+
+ public class MediaRouteControllerDialogFragment extends androidx.fragment.app.DialogFragment {
+ ctor public MediaRouteControllerDialogFragment();
+ method public androidx.mediarouter.app.MediaRouteControllerDialog onCreateControllerDialog(android.content.Context, android.os.Bundle?);
+ }
+
+ public class MediaRouteDialogFactory {
+ ctor public MediaRouteDialogFactory();
+ method public static androidx.mediarouter.app.MediaRouteDialogFactory getDefault();
+ method public androidx.mediarouter.app.MediaRouteChooserDialogFragment onCreateChooserDialogFragment();
+ method public androidx.mediarouter.app.MediaRouteControllerDialogFragment onCreateControllerDialogFragment();
+ }
+
+ public class MediaRouteDiscoveryFragment extends androidx.fragment.app.Fragment {
+ ctor public MediaRouteDiscoveryFragment();
+ method public androidx.mediarouter.media.MediaRouter getMediaRouter();
+ method public androidx.mediarouter.media.MediaRouteSelector getRouteSelector();
+ method public androidx.mediarouter.media.MediaRouter.Callback? onCreateCallback();
+ method public int onPrepareCallbackFlags();
+ method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
+ }
+
+ public final class SystemOutputSwitcherDialogController {
+ method public static boolean showDialog(android.content.Context);
+ }
+
+}
+
+package androidx.mediarouter.media {
+
+ public final class MediaControlIntent {
+ field public static final String ACTION_END_SESSION = "android.media.intent.action.END_SESSION";
+ field public static final String ACTION_ENQUEUE = "android.media.intent.action.ENQUEUE";
+ field public static final String ACTION_GET_SESSION_STATUS = "android.media.intent.action.GET_SESSION_STATUS";
+ field public static final String ACTION_GET_STATUS = "android.media.intent.action.GET_STATUS";
+ field public static final String ACTION_PAUSE = "android.media.intent.action.PAUSE";
+ field public static final String ACTION_PLAY = "android.media.intent.action.PLAY";
+ field public static final String ACTION_REMOVE = "android.media.intent.action.REMOVE";
+ field public static final String ACTION_RESUME = "android.media.intent.action.RESUME";
+ field public static final String ACTION_SEEK = "android.media.intent.action.SEEK";
+ field public static final String ACTION_SEND_MESSAGE = "android.media.intent.action.SEND_MESSAGE";
+ field public static final String ACTION_START_SESSION = "android.media.intent.action.START_SESSION";
+ field public static final String ACTION_STOP = "android.media.intent.action.STOP";
+ field public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+ field public static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+ field public static final String CATEGORY_REMOTE_PLAYBACK = "android.media.intent.category.REMOTE_PLAYBACK";
+ field public static final int ERROR_INVALID_ITEM_ID = 3; // 0x3
+ field public static final int ERROR_INVALID_SESSION_ID = 2; // 0x2
+ field public static final int ERROR_UNKNOWN = 0; // 0x0
+ field public static final int ERROR_UNSUPPORTED_OPERATION = 1; // 0x1
+ field public static final String EXTRA_ERROR_CODE = "android.media.intent.extra.ERROR_CODE";
+ field public static final String EXTRA_ITEM_CONTENT_POSITION = "android.media.intent.extra.ITEM_POSITION";
+ field public static final String EXTRA_ITEM_HTTP_HEADERS = "android.media.intent.extra.HTTP_HEADERS";
+ field public static final String EXTRA_ITEM_ID = "android.media.intent.extra.ITEM_ID";
+ field public static final String EXTRA_ITEM_METADATA = "android.media.intent.extra.ITEM_METADATA";
+ field public static final String EXTRA_ITEM_STATUS = "android.media.intent.extra.ITEM_STATUS";
+ field public static final String EXTRA_ITEM_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.ITEM_STATUS_UPDATE_RECEIVER";
+ field public static final String EXTRA_MESSAGE = "android.media.intent.extra.MESSAGE";
+ field public static final String EXTRA_MESSAGE_RECEIVER = "android.media.intent.extra.MESSAGE_RECEIVER";
+ field public static final String EXTRA_SESSION_ID = "android.media.intent.extra.SESSION_ID";
+ field public static final String EXTRA_SESSION_STATUS = "android.media.intent.extra.SESSION_STATUS";
+ field public static final String EXTRA_SESSION_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.SESSION_STATUS_UPDATE_RECEIVER";
+ }
+
+ public final class MediaItemMetadata {
+ field public static final String KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+ field public static final String KEY_ALBUM_TITLE = "android.media.metadata.ALBUM_TITLE";
+ field public static final String KEY_ARTIST = "android.media.metadata.ARTIST";
+ field public static final String KEY_ARTWORK_URI = "android.media.metadata.ARTWORK_URI";
+ field public static final String KEY_AUTHOR = "android.media.metadata.AUTHOR";
+ field public static final String KEY_COMPOSER = "android.media.metadata.COMPOSER";
+ field public static final String KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+ field public static final String KEY_DURATION = "android.media.metadata.DURATION";
+ field public static final String KEY_TITLE = "android.media.metadata.TITLE";
+ field public static final String KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+ field public static final String KEY_YEAR = "android.media.metadata.YEAR";
+ }
+
+ public final class MediaItemStatus {
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaItemStatus? fromBundle(android.os.Bundle?);
+ method public long getContentDuration();
+ method public long getContentPosition();
+ method public android.os.Bundle? getExtras();
+ method public int getPlaybackState();
+ method public long getTimestamp();
+ field public static final String EXTRA_HTTP_RESPONSE_HEADERS = "android.media.status.extra.HTTP_RESPONSE_HEADERS";
+ field public static final String EXTRA_HTTP_STATUS_CODE = "android.media.status.extra.HTTP_STATUS_CODE";
+ field public static final int PLAYBACK_STATE_BUFFERING = 3; // 0x3
+ field public static final int PLAYBACK_STATE_CANCELED = 5; // 0x5
+ field public static final int PLAYBACK_STATE_ERROR = 7; // 0x7
+ field public static final int PLAYBACK_STATE_FINISHED = 4; // 0x4
+ field public static final int PLAYBACK_STATE_INVALIDATED = 6; // 0x6
+ field public static final int PLAYBACK_STATE_PAUSED = 2; // 0x2
+ field public static final int PLAYBACK_STATE_PENDING = 0; // 0x0
+ field public static final int PLAYBACK_STATE_PLAYING = 1; // 0x1
+ }
+
+ public static final class MediaItemStatus.Builder {
+ ctor public MediaItemStatus.Builder(androidx.mediarouter.media.MediaItemStatus);
+ ctor public MediaItemStatus.Builder(int);
+ method public androidx.mediarouter.media.MediaItemStatus build();
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setContentDuration(long);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setContentPosition(long);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setExtras(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setPlaybackState(int);
+ method public androidx.mediarouter.media.MediaItemStatus.Builder setTimestamp(long);
+ }
+
+ public final class MediaRouteDescriptor {
+ method public android.os.Bundle asBundle();
+ method public boolean canDisconnectAndKeepPlaying();
+ method public static androidx.mediarouter.media.MediaRouteDescriptor? fromBundle(android.os.Bundle?);
+ method public java.util.Set<java.lang.String!> getAllowedPackages();
+ method public int getConnectionState();
+ method public java.util.List<android.content.IntentFilter!> getControlFilters();
+ method public java.util.Set<java.lang.String!> getDeduplicationIds();
+ method public String? getDescription();
+ method public int getDeviceType();
+ method public android.os.Bundle? getExtras();
+ method public android.net.Uri? getIconUri();
+ method public String getId();
+ method public String getName();
+ method public int getPlaybackStream();
+ method public int getPlaybackType();
+ method public int getPresentationDisplayId();
+ method public android.content.IntentSender? getSettingsActivity();
+ method public int getVolume();
+ method public int getVolumeHandling();
+ method public int getVolumeMax();
+ method @Deprecated public boolean isConnecting();
+ method public boolean isDynamicGroupRoute();
+ method public boolean isEnabled();
+ method public boolean isSystemRoute();
+ method public boolean isValid();
+ method public boolean isVisibilityPublic();
+ }
+
+ public static final class MediaRouteDescriptor.Builder {
+ ctor public MediaRouteDescriptor.Builder(androidx.mediarouter.media.MediaRouteDescriptor);
+ ctor public MediaRouteDescriptor.Builder(String, String);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder addControlFilter(android.content.IntentFilter);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder addControlFilters(java.util.Collection<android.content.IntentFilter!>);
+ method public androidx.mediarouter.media.MediaRouteDescriptor build();
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder clearControlFilters();
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setCanDisconnect(boolean);
+ method @Deprecated public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnecting(boolean);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnectionState(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeduplicationIds(java.util.Set<java.lang.String!>);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDescription(String?);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeviceType(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setEnabled(boolean);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setExtras(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setIconUri(android.net.Uri);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setId(String);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setIsDynamicGroupRoute(boolean);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setName(String);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPlaybackStream(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPlaybackType(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPresentationDisplayId(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setSettingsActivity(android.content.IntentSender?);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityPublic();
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityRestricted(java.util.Set<java.lang.String!>);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolume(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeHandling(int);
+ method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeMax(int);
+ }
+
+ public final class MediaRouteDiscoveryRequest {
+ ctor public MediaRouteDiscoveryRequest(androidx.mediarouter.media.MediaRouteSelector, boolean);
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaRouteDiscoveryRequest? fromBundle(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaRouteSelector getSelector();
+ method public boolean isActiveScan();
+ method public boolean isValid();
+ }
+
+ public abstract class MediaRouteProvider {
+ ctor public MediaRouteProvider(android.content.Context);
+ method public final android.content.Context getContext();
+ method public final androidx.mediarouter.media.MediaRouteProviderDescriptor? getDescriptor();
+ method public final androidx.mediarouter.media.MediaRouteDiscoveryRequest? getDiscoveryRequest();
+ method public final android.os.Handler getHandler();
+ method public final androidx.mediarouter.media.MediaRouteProvider.ProviderMetadata getMetadata();
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController? onCreateDynamicGroupRouteController(String);
+ method public androidx.mediarouter.media.MediaRouteProvider.RouteController? onCreateRouteController(String);
+ method public void onDiscoveryRequestChanged(androidx.mediarouter.media.MediaRouteDiscoveryRequest?);
+ method public final void setCallback(androidx.mediarouter.media.MediaRouteProvider.Callback?);
+ method public final void setDescriptor(androidx.mediarouter.media.MediaRouteProviderDescriptor?);
+ method public final void setDiscoveryRequest(androidx.mediarouter.media.MediaRouteDiscoveryRequest?);
+ }
+
+ public abstract static class MediaRouteProvider.Callback {
+ ctor public MediaRouteProvider.Callback();
+ method public void onDescriptorChanged(androidx.mediarouter.media.MediaRouteProvider, androidx.mediarouter.media.MediaRouteProviderDescriptor?);
+ }
+
+ public abstract static class MediaRouteProvider.DynamicGroupRouteController extends androidx.mediarouter.media.MediaRouteProvider.RouteController {
+ ctor public MediaRouteProvider.DynamicGroupRouteController();
+ method public String? getGroupableSelectionTitle();
+ method public String? getTransferableSectionTitle();
+ method public final void notifyDynamicRoutesChanged(androidx.mediarouter.media.MediaRouteDescriptor, java.util.Collection<androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor!>);
+ method @Deprecated public final void notifyDynamicRoutesChanged(java.util.Collection<androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor!>);
+ method public abstract void onAddMemberRoute(String);
+ method public abstract void onRemoveMemberRoute(String);
+ method public abstract void onUpdateMemberRoutes(java.util.List<java.lang.String!>?);
+ }
+
+ public static final class MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor {
+ method public androidx.mediarouter.media.MediaRouteDescriptor getRouteDescriptor();
+ method public int getSelectionState();
+ method public boolean isGroupable();
+ method public boolean isTransferable();
+ method public boolean isUnselectable();
+ field public static final int SELECTED = 3; // 0x3
+ field public static final int SELECTING = 2; // 0x2
+ field public static final int UNSELECTED = 1; // 0x1
+ field public static final int UNSELECTING = 0; // 0x0
+ }
+
+ public static final class MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder {
+ ctor public MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder(androidx.mediarouter.media.MediaRouteDescriptor);
+ ctor public MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder(androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor build();
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setIsGroupable(boolean);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setIsTransferable(boolean);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setIsUnselectable(boolean);
+ method public androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor.Builder setSelectionState(int);
+ }
+
+ public static final class MediaRouteProvider.ProviderMetadata {
+ method public android.content.ComponentName getComponentName();
+ method public String getPackageName();
+ }
+
+ public abstract static class MediaRouteProvider.RouteController {
+ ctor public MediaRouteProvider.RouteController();
+ method public boolean onControlRequest(android.content.Intent, androidx.mediarouter.media.MediaRouter.ControlRequestCallback?);
+ method public void onRelease();
+ method public void onSelect();
+ method public void onSetVolume(int);
+ method @Deprecated public void onUnselect();
+ method public void onUnselect(int);
+ method public void onUpdateVolume(int);
+ }
+
+ public final class MediaRouteProviderDescriptor {
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaRouteProviderDescriptor? fromBundle(android.os.Bundle?);
+ method public java.util.List<androidx.mediarouter.media.MediaRouteDescriptor!> getRoutes();
+ method public boolean isValid();
+ method public boolean supportsDynamicGroupRoute();
+ }
+
+ public static final class MediaRouteProviderDescriptor.Builder {
+ ctor public MediaRouteProviderDescriptor.Builder();
+ ctor public MediaRouteProviderDescriptor.Builder(androidx.mediarouter.media.MediaRouteProviderDescriptor);
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder addRoute(androidx.mediarouter.media.MediaRouteDescriptor);
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder addRoutes(java.util.Collection<androidx.mediarouter.media.MediaRouteDescriptor!>);
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor build();
+ method public androidx.mediarouter.media.MediaRouteProviderDescriptor.Builder setSupportsDynamicGroupRoute(boolean);
+ }
+
+ public abstract class MediaRouteProviderService extends android.app.Service {
+ ctor public MediaRouteProviderService();
+ method public androidx.mediarouter.media.MediaRouteProvider? getMediaRouteProvider();
+ method public android.os.IBinder? onBind(android.content.Intent);
+ method public abstract androidx.mediarouter.media.MediaRouteProvider? onCreateMediaRouteProvider();
+ field public static final String SERVICE_INTERFACE = "android.media.MediaRouteProviderService";
+ }
+
+ public final class MediaRouteSelector {
+ method public android.os.Bundle asBundle();
+ method public boolean contains(androidx.mediarouter.media.MediaRouteSelector);
+ method public static androidx.mediarouter.media.MediaRouteSelector? fromBundle(android.os.Bundle?);
+ method public java.util.List<java.lang.String!> getControlCategories();
+ method public boolean hasControlCategory(String?);
+ method public boolean isEmpty();
+ method public boolean isValid();
+ method public boolean matchesControlFilters(java.util.List<android.content.IntentFilter!>?);
+ field public static final androidx.mediarouter.media.MediaRouteSelector! EMPTY;
+ }
+
+ public static final class MediaRouteSelector.Builder {
+ ctor public MediaRouteSelector.Builder();
+ ctor public MediaRouteSelector.Builder(androidx.mediarouter.media.MediaRouteSelector);
+ method public androidx.mediarouter.media.MediaRouteSelector.Builder addControlCategories(java.util.Collection<java.lang.String!>);
+ method public androidx.mediarouter.media.MediaRouteSelector.Builder addControlCategory(String);
+ method public androidx.mediarouter.media.MediaRouteSelector.Builder addSelector(androidx.mediarouter.media.MediaRouteSelector);
+ method public androidx.mediarouter.media.MediaRouteSelector build();
+ }
+
+ public final class MediaRouter {
+ method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback);
+ method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback, int);
+ method @MainThread public void addProvider(androidx.mediarouter.media.MediaRouteProvider);
+ method @Deprecated @MainThread public void addRemoteControlClient(Object);
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo? getBluetoothRoute();
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo getDefaultRoute();
+ method @MainThread public static androidx.mediarouter.media.MediaRouter getInstance(android.content.Context);
+ method public android.support.v4.media.session.MediaSessionCompat.Token? getMediaSessionToken();
+ method @MainThread public java.util.List<androidx.mediarouter.media.MediaRouter.ProviderInfo!> getProviders();
+ method @MainThread public androidx.mediarouter.media.MediaRouterParams? getRouterParams();
+ method @MainThread public java.util.List<androidx.mediarouter.media.MediaRouter.RouteInfo!> getRoutes();
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo getSelectedRoute();
+ method @MainThread public boolean isRouteAvailable(androidx.mediarouter.media.MediaRouteSelector, int);
+ method @MainThread public void removeCallback(androidx.mediarouter.media.MediaRouter.Callback);
+ method @MainThread public void removeProvider(androidx.mediarouter.media.MediaRouteProvider);
+ method @Deprecated @MainThread public void removeRemoteControlClient(Object);
+ method @MainThread public void selectRoute(androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method @MainThread public void setMediaSession(Object?);
+ method @MainThread public void setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat?);
+ method @MainThread public void setOnPrepareTransferListener(androidx.mediarouter.media.MediaRouter.OnPrepareTransferListener?);
+ method @MainThread public void setRouteListingPreference(androidx.mediarouter.media.RouteListingPreference?);
+ method @MainThread public void setRouterParams(androidx.mediarouter.media.MediaRouterParams?);
+ method @MainThread public void unselect(int);
+ method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo updateSelectedRoute(androidx.mediarouter.media.MediaRouteSelector);
+ field public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1; // 0x1
+ field public static final int AVAILABILITY_FLAG_REQUIRE_MATCH = 2; // 0x2
+ field public static final int CALLBACK_FLAG_FORCE_DISCOVERY = 8; // 0x8
+ field public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1; // 0x1
+ field public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 4; // 0x4
+ field public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 2; // 0x2
+ field public static final int UNSELECT_REASON_DISCONNECTED = 1; // 0x1
+ field public static final int UNSELECT_REASON_ROUTE_CHANGED = 3; // 0x3
+ field public static final int UNSELECT_REASON_STOPPED = 2; // 0x2
+ field public static final int UNSELECT_REASON_UNKNOWN = 0; // 0x0
+ }
+
+ public abstract static class MediaRouter.Callback {
+ ctor public MediaRouter.Callback();
+ method public void onProviderAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo);
+ method public void onProviderChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo);
+ method public void onProviderRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.ProviderInfo);
+ method public void onRouteAdded(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRoutePresentationDisplayChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteRemoved(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method @Deprecated public void onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int);
+ method public void onRouteSelected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method @Deprecated public void onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void onRouteUnselected(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo, int);
+ method public void onRouteVolumeChanged(androidx.mediarouter.media.MediaRouter, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ }
+
+ public abstract static class MediaRouter.ControlRequestCallback {
+ ctor public MediaRouter.ControlRequestCallback();
+ method public void onError(String?, android.os.Bundle?);
+ method public void onResult(android.os.Bundle?);
+ }
+
+ public static interface MediaRouter.OnPrepareTransferListener {
+ method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!>? onPrepareTransfer(androidx.mediarouter.media.MediaRouter.RouteInfo, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ }
+
+ public static final class MediaRouter.ProviderInfo {
+ method public android.content.ComponentName getComponentName();
+ method public String getPackageName();
+ method @MainThread public androidx.mediarouter.media.MediaRouteProvider getProviderInstance();
+ method @MainThread public java.util.List<androidx.mediarouter.media.MediaRouter.RouteInfo!> getRoutes();
+ }
+
+ public static class MediaRouter.RouteInfo {
+ method public boolean canDisconnect();
+ method public int getConnectionState();
+ method public java.util.List<android.content.IntentFilter!> getControlFilters();
+ method public String? getDescription();
+ method public int getDeviceType();
+ method public android.os.Bundle? getExtras();
+ method public android.net.Uri? getIconUri();
+ method public String getId();
+ method public String getName();
+ method public int getPlaybackStream();
+ method public int getPlaybackType();
+ method @MainThread public android.view.Display? getPresentationDisplay();
+ method public androidx.mediarouter.media.MediaRouter.ProviderInfo getProvider();
+ method public android.content.IntentSender? getSettingsIntent();
+ method public int getVolume();
+ method public int getVolumeHandling();
+ method public int getVolumeMax();
+ method @MainThread public boolean isBluetooth();
+ method @Deprecated public boolean isConnecting();
+ method @MainThread public boolean isDefault();
+ method public boolean isDeviceSpeaker();
+ method public boolean isEnabled();
+ method @MainThread public boolean isSelected();
+ method public boolean isSystemRoute();
+ method @MainThread public boolean matchesSelector(androidx.mediarouter.media.MediaRouteSelector);
+ method @MainThread public void requestSetVolume(int);
+ method @MainThread public void requestUpdateVolume(int);
+ method @MainThread public void select();
+ method @MainThread public void sendControlRequest(android.content.Intent, androidx.mediarouter.media.MediaRouter.ControlRequestCallback?);
+ method @MainThread public boolean supportsControlAction(String, String);
+ method @MainThread public boolean supportsControlCategory(String);
+ method @MainThread public boolean supportsControlRequest(android.content.Intent);
+ field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
+ field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
+ field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
+ field public static final int DEVICE_TYPE_AUDIO_VIDEO_RECEIVER = 4; // 0x4
+ field public static final int DEVICE_TYPE_BLE_HEADSET = 22; // 0x16
+ field public static final int DEVICE_TYPE_BLUETOOTH_A2DP = 3; // 0x3
+ field public static final int DEVICE_TYPE_BUILTIN_SPEAKER = 12; // 0xc
+ field public static final int DEVICE_TYPE_CAR = 9; // 0x9
+ field public static final int DEVICE_TYPE_COMPUTER = 7; // 0x7
+ field public static final int DEVICE_TYPE_DOCK = 19; // 0x13
+ field public static final int DEVICE_TYPE_GAME_CONSOLE = 8; // 0x8
+ field public static final int DEVICE_TYPE_GROUP = 1000; // 0x3e8
+ field public static final int DEVICE_TYPE_HDMI = 16; // 0x10
+ field public static final int DEVICE_TYPE_HDMI_ARC = 23; // 0x17
+ field public static final int DEVICE_TYPE_HDMI_EARC = 24; // 0x18
+ field public static final int DEVICE_TYPE_HEARING_AID = 21; // 0x15
+ field public static final int DEVICE_TYPE_REMOTE_SPEAKER = 2; // 0x2
+ field public static final int DEVICE_TYPE_SMARTPHONE = 11; // 0xb
+ field public static final int DEVICE_TYPE_SMARTWATCH = 10; // 0xa
+ field @Deprecated public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+ field public static final int DEVICE_TYPE_TABLET = 5; // 0x5
+ field public static final int DEVICE_TYPE_TABLET_DOCKED = 6; // 0x6
+ field public static final int DEVICE_TYPE_TV = 1; // 0x1
+ field public static final int DEVICE_TYPE_USB_ACCESSORY = 18; // 0x12
+ field public static final int DEVICE_TYPE_USB_DEVICE = 17; // 0x11
+ field public static final int DEVICE_TYPE_USB_HEADSET = 20; // 0x14
+ field public static final int DEVICE_TYPE_WIRED_HEADPHONES = 14; // 0xe
+ field public static final int DEVICE_TYPE_WIRED_HEADSET = 13; // 0xd
+ field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
+ field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
+ field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+ field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+ }
+
+ public class MediaRouterParams {
+ method public int getDialogType();
+ method public boolean isMediaTransferReceiverEnabled();
+ method public boolean isOutputSwitcherEnabled();
+ method public boolean isTransferToLocalEnabled();
+ field public static final int DIALOG_TYPE_DEFAULT = 1; // 0x1
+ field public static final int DIALOG_TYPE_DYNAMIC_GROUP = 2; // 0x2
+ field public static final String ENABLE_GROUP_VOLUME_UX = "androidx.mediarouter.media.MediaRouterParams.ENABLE_GROUP_VOLUME_UX";
+ }
+
+ public static final class MediaRouterParams.Builder {
+ ctor public MediaRouterParams.Builder();
+ ctor public MediaRouterParams.Builder(androidx.mediarouter.media.MediaRouterParams);
+ method public androidx.mediarouter.media.MediaRouterParams build();
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setDialogType(int);
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setMediaTransferReceiverEnabled(boolean);
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setOutputSwitcherEnabled(boolean);
+ method public androidx.mediarouter.media.MediaRouterParams.Builder setTransferToLocalEnabled(boolean);
+ }
+
+ public final class MediaSessionStatus {
+ method public android.os.Bundle asBundle();
+ method public static androidx.mediarouter.media.MediaSessionStatus? fromBundle(android.os.Bundle?);
+ method public android.os.Bundle? getExtras();
+ method public int getSessionState();
+ method public long getTimestamp();
+ method public boolean isQueuePaused();
+ field public static final int SESSION_STATE_ACTIVE = 0; // 0x0
+ field public static final int SESSION_STATE_ENDED = 1; // 0x1
+ field public static final int SESSION_STATE_INVALIDATED = 2; // 0x2
+ }
+
+ public static final class MediaSessionStatus.Builder {
+ ctor public MediaSessionStatus.Builder(androidx.mediarouter.media.MediaSessionStatus);
+ ctor public MediaSessionStatus.Builder(int);
+ method public androidx.mediarouter.media.MediaSessionStatus build();
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setExtras(android.os.Bundle?);
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setQueuePaused(boolean);
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setSessionState(int);
+ method public androidx.mediarouter.media.MediaSessionStatus.Builder setTimestamp(long);
+ }
+
+ public final class MediaTransferReceiver extends android.content.BroadcastReceiver {
+ ctor public MediaTransferReceiver();
+ method public void onReceive(android.content.Context, android.content.Intent);
+ }
+
+ public class RemotePlaybackClient {
+ ctor public RemotePlaybackClient(android.content.Context, androidx.mediarouter.media.MediaRouter.RouteInfo);
+ method public void endSession(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void enqueue(android.net.Uri, String?, android.os.Bundle?, long, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public String? getSessionId();
+ method public void getSessionStatus(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void getStatus(String, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public boolean hasSession();
+ method public boolean isMessagingSupported();
+ method public boolean isQueuingSupported();
+ method public boolean isRemotePlaybackSupported();
+ method public boolean isSessionManagementSupported();
+ method public void pause(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void play(android.net.Uri, String?, android.os.Bundle?, long, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public void release();
+ method public void remove(String, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public void resume(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void seek(String, long, android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.ItemActionCallback?);
+ method public void sendMessage(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void setOnMessageReceivedListener(androidx.mediarouter.media.RemotePlaybackClient.OnMessageReceivedListener?);
+ method public void setSessionId(String?);
+ method public void setStatusCallback(androidx.mediarouter.media.RemotePlaybackClient.StatusCallback?);
+ method public void startSession(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ method public void stop(android.os.Bundle?, androidx.mediarouter.media.RemotePlaybackClient.SessionActionCallback?);
+ }
+
+ public abstract static class RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.ActionCallback();
+ method public void onError(String?, int, android.os.Bundle?);
+ }
+
+ public abstract static class RemotePlaybackClient.ItemActionCallback extends androidx.mediarouter.media.RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.ItemActionCallback();
+ method public void onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus?, String, androidx.mediarouter.media.MediaItemStatus);
+ }
+
+ public static interface RemotePlaybackClient.OnMessageReceivedListener {
+ method public void onMessageReceived(String, android.os.Bundle?);
+ }
+
+ public abstract static class RemotePlaybackClient.SessionActionCallback extends androidx.mediarouter.media.RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.SessionActionCallback();
+ method public void onResult(android.os.Bundle, String, androidx.mediarouter.media.MediaSessionStatus?);
+ }
+
+ public abstract static class RemotePlaybackClient.StatusCallback {
+ ctor public RemotePlaybackClient.StatusCallback();
+ method public void onItemStatusChanged(android.os.Bundle?, String, androidx.mediarouter.media.MediaSessionStatus?, String, androidx.mediarouter.media.MediaItemStatus);
+ method public void onSessionChanged(String?);
+ method public void onSessionStatusChanged(android.os.Bundle?, String, androidx.mediarouter.media.MediaSessionStatus?);
+ }
+
+ public final class RouteListingPreference {
+ method public java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!> getItems();
+ method public android.content.ComponentName? getLinkedItemComponentName();
+ method public boolean isSystemOrderingEnabled();
+ field public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA";
+ field public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID";
+ }
+
+ public static final class RouteListingPreference.Builder {
+ ctor public RouteListingPreference.Builder();
+ method public androidx.mediarouter.media.RouteListingPreference build();
+ method public androidx.mediarouter.media.RouteListingPreference.Builder setItems(java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!>);
+ method public androidx.mediarouter.media.RouteListingPreference.Builder setLinkedItemComponentName(android.content.ComponentName?);
+ method public androidx.mediarouter.media.RouteListingPreference.Builder setSystemOrderingEnabled(boolean);
+ }
+
+ public static final class RouteListingPreference.Item {
+ method public CharSequence? getCustomSubtextMessage();
+ method public int getFlags();
+ method public String getRouteId();
+ method public int getSelectionBehavior();
+ method public int getSubText();
+ field public static final int FLAG_ONGOING_SESSION = 1; // 0x1
+ field public static final int FLAG_ONGOING_SESSION_MANAGED = 2; // 0x2
+ field public static final int FLAG_SUGGESTED = 4; // 0x4
+ field public static final int SELECTION_BEHAVIOR_GO_TO_APP = 2; // 0x2
+ field public static final int SELECTION_BEHAVIOR_NONE = 0; // 0x0
+ field public static final int SELECTION_BEHAVIOR_TRANSFER = 1; // 0x1
+ field public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 4; // 0x4
+ field public static final int SUBTEXT_CUSTOM = 10000; // 0x2710
+ field public static final int SUBTEXT_DEVICE_LOW_POWER = 5; // 0x5
+ field public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 3; // 0x3
+ field public static final int SUBTEXT_ERROR_UNKNOWN = 1; // 0x1
+ field public static final int SUBTEXT_NONE = 0; // 0x0
+ field public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 2; // 0x2
+ field public static final int SUBTEXT_TRACK_UNSUPPORTED = 7; // 0x7
+ field public static final int SUBTEXT_UNAUTHORIZED = 6; // 0x6
+ }
+
+ public static final class RouteListingPreference.Item.Builder {
+ ctor public RouteListingPreference.Item.Builder(String);
+ method public androidx.mediarouter.media.RouteListingPreference.Item build();
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setCustomSubtextMessage(CharSequence?);
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setFlags(int);
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSelectionBehavior(int);
+ method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSubText(int);
+ }
+
+}
+
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 2fc6774..5970697 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -26,5 +26,5 @@
# Disable docs
androidx.enableDocumentation=false
androidx.playground.snapshotBuildId=11349412
-androidx.playground.metalavaBuildId=11398882
+androidx.playground.metalavaBuildId=11427892
androidx.studio.type=playground
\ No newline at end of file
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 c7e868f..7d3b798 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
@@ -41,6 +41,7 @@
import com.google.common.truth.Truth.assertThat
import dalvik.system.BaseDexClassLoader
import java.io.File
+import java.util.concurrent.Executor
import org.junit.Assert.assertThrows
import org.junit.Assume.assumeTrue
import org.junit.Before
@@ -319,8 +320,20 @@
var sdkActivityHandlers: MutableMap<IBinder, SdkSandboxActivityHandlerCompat> =
mutableMapOf()
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw UnsupportedOperationException("Shouldn't be called")
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LoadSdkCompatException.LOAD_SDK_INTERNAL_ERROR,
+ "Shouldn't be called"
+ )
+ )
+ }
}
override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
index ee66f50..49aaf76 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
@@ -34,6 +34,7 @@
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
import java.io.File
+import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -160,8 +161,20 @@
private class NoOpImpl : SdkSandboxControllerCompat.SandboxControllerImpl {
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw UnsupportedOperationException("NoOp")
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LoadSdkCompatException.LOAD_SDK_INTERNAL_ERROR,
+ "NoOp"
+ )
+ )
+ }
}
override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
index eb195d6..a57674c 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
@@ -20,9 +20,11 @@
import android.os.IBinder
import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import java.util.concurrent.Executor
/**
* Local implementation that will be injected to locally loaded SDKs.
@@ -32,8 +34,21 @@
private val locallyLoadedSdks: LocallyLoadedSdks,
private val appOwnedSdkRegistry: AppOwnedSdkRegistry
) : SdkSandboxControllerCompat.SandboxControllerImpl {
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw UnsupportedOperationException("Shouldn't be called")
+
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LoadSdkCompatException.LOAD_SDK_INTERNAL_ERROR,
+ "Shouldn't be called"
+ )
+ )
+ }
}
override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
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 d815735..c3a7b6d 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
@@ -30,6 +30,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Assert
@@ -220,8 +221,20 @@
) : SdkSandboxControllerCompat.SandboxControllerImpl {
var token: IBinder? = null
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw UnsupportedOperationException("Shouldn't be called")
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LoadSdkCompatException.LOAD_SDK_INTERNAL_ERROR,
+ "Shouldn't be called"
+ )
+ )
+ }
}
override fun getSandboxedSdks() = sandboxedSdks
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
index 3d1a408..518a230 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
@@ -34,6 +34,12 @@
import androidx.privacysandbox.sdkruntime.core.controller.impl.LocalImpl
import androidx.privacysandbox.sdkruntime.core.controller.impl.NoOpImpl
import androidx.privacysandbox.sdkruntime.core.controller.impl.PlatformUDCImpl
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.coroutines.Continuation
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
+import kotlinx.coroutines.suspendCancellableCoroutine
import org.jetbrains.annotations.TestOnly
/**
@@ -65,8 +71,15 @@
* @return [SandboxedSdkCompat] from SDK on a successful run.
* @throws [LoadSdkCompatException] on fail.
*/
- suspend fun loadSdk(sdkName: String, params: Bundle) =
- controllerImpl.loadSdk(sdkName, params)
+ suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat =
+ suspendCancellableCoroutine { continuation ->
+ controllerImpl.loadSdk(
+ sdkName,
+ params,
+ Runnable::run,
+ ContinuationLoadSdkCallback(continuation)
+ )
+ }
/**
* Fetches information about Sdks that are loaded in the sandbox or locally.
@@ -118,7 +131,7 @@
@RestrictTo(LIBRARY_GROUP)
interface SandboxControllerImpl {
- suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat
+ fun loadSdk(sdkName: String, params: Bundle, executor: Executor, callback: LoadSdkCallback)
fun getSandboxedSdks(): List<SandboxedSdkCompat>
@@ -132,6 +145,12 @@
)
}
+ @RestrictTo(LIBRARY_GROUP)
+ interface LoadSdkCallback {
+ fun onResult(result: SandboxedSdkCompat)
+ fun onError(error: LoadSdkCompatException)
+ }
+
companion object {
private var localImpl: SandboxControllerImpl? = null
@@ -186,4 +205,24 @@
throw UnsupportedOperationException("SDK should be loaded locally on API below 34")
}
}
+
+ private class ContinuationLoadSdkCallback(
+ private val continuation: Continuation<SandboxedSdkCompat>
+ ) : LoadSdkCallback, AtomicBoolean(false) {
+ override fun onResult(result: SandboxedSdkCompat) {
+ // Do not attempt to resume more than once, even if the caller is buggy.
+ if (compareAndSet(false, true)) {
+ continuation.resume(result)
+ }
+ }
+
+ override fun onError(error: LoadSdkCompatException) {
+ // Do not attempt to resume more than once, even if the caller is buggy.
+ if (compareAndSet(false, true)) {
+ continuation.resumeWithException(error)
+ }
+ }
+
+ override fun toString() = "ContinuationLoadSdkCallback(outcomeReceived = ${get()})"
+ }
}
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 f7c1f54..0b9bcf4 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
@@ -24,6 +24,7 @@
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import java.util.concurrent.Executor
/**
* Wrapper for client provided implementation of [SdkSandboxControllerCompat].
@@ -34,11 +35,20 @@
private val clientVersion: Int
) : SdkSandboxControllerCompat.SandboxControllerImpl {
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw LoadSdkCompatException(
- LOAD_SDK_NOT_FOUND,
- "Not supported for locally loaded SDKs yet"
- )
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LOAD_SDK_NOT_FOUND,
+ "Not supported for locally loaded SDKs yet"
+ )
+ )
+ }
}
override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
index 6e0727d..102d2e3 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
@@ -23,17 +23,27 @@
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import java.util.concurrent.Executor
/**
* NoOp implementation for cases when [SdkSandboxControllerCompat] not supported.
*/
internal class NoOpImpl : SdkSandboxControllerCompat.SandboxControllerImpl {
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw LoadSdkCompatException(
- LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
- "Loading SDK not supported on this device"
- )
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
+ "Loading SDK not supported on this device"
+ )
+ )
+ }
}
override fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformSdkLoader.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformSdkLoader.kt
index 72e7850..138b2b3 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformSdkLoader.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformSdkLoader.kt
@@ -17,18 +17,20 @@
package androidx.privacysandbox.sdkruntime.core.controller.impl
import android.app.sdksandbox.LoadSdkException
+import android.app.sdksandbox.SandboxedSdk
import android.app.sdksandbox.sdkprovider.SdkSandboxController
import android.os.Bundle
+import android.os.OutcomeReceiver
import android.os.ext.SdkExtensions
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresExtension
import androidx.core.os.BuildCompat
-import androidx.core.os.asOutcomeReceiver
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.toLoadCompatSdkException
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
-import kotlinx.coroutines.suspendCancellableCoroutine
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import java.util.concurrent.Executor
/**
* Trying to load SDK using [SdkSandboxController].
@@ -39,47 +41,74 @@
private val loaderImpl: LoaderImpl
) {
- suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat =
- loaderImpl.loadSdk(sdkName, params)
+ fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ receiver: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ loaderImpl.loadSdk(sdkName, params, executor, receiver)
+ }
private interface LoaderImpl {
- suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat
+ fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ )
}
/**
* Implementation for cases when API not supported by [SdkSandboxController]
*/
private object FailImpl : LoaderImpl {
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- throw LoadSdkCompatException(
- LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
- "Loading SDK not supported on this device"
- )
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ executor.execute {
+ callback.onError(
+ LoadSdkCompatException(
+ LoadSdkCompatException.LOAD_SDK_NOT_FOUND,
+ "Loading SDK not supported on this device"
+ )
+ )
+ }
}
}
/**
* Implementation for AdServices V10.
*/
+ @RequiresApi(34)
@RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 10)
private class ApiAdServicesV10Impl(
private val controller: SdkSandboxController
) : LoaderImpl {
@DoNotInline
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat {
- try {
- val sandboxedSdk = suspendCancellableCoroutine { continuation ->
- controller.loadSdk(
- sdkName,
- params,
- Runnable::run,
- continuation.asOutcomeReceiver()
- )
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ controller.loadSdk(
+ sdkName,
+ params,
+ executor,
+ object : OutcomeReceiver<SandboxedSdk, LoadSdkException> {
+ override fun onResult(result: SandboxedSdk) {
+ callback.onResult(SandboxedSdkCompat(result))
+ }
+
+ override fun onError(error: LoadSdkException) {
+ callback.onError(toLoadCompatSdkException(error))
+ }
}
- return SandboxedSdkCompat(sandboxedSdk)
- } catch (ex: LoadSdkException) {
- throw toLoadCompatSdkException(ex)
- }
+ )
}
}
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
index 401fcf9..7b1dc7f 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
@@ -32,6 +32,7 @@
import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import java.util.concurrent.Executor
/**
* Implementation that delegates to platform [SdkSandboxController] for Android U.
@@ -47,8 +48,14 @@
private val compatToPlatformMap =
hashMapOf<SdkSandboxActivityHandlerCompat, SdkSandboxActivityHandler>()
- override suspend fun loadSdk(sdkName: String, params: Bundle): SandboxedSdkCompat =
- sdkLoader.loadSdk(sdkName, params)
+ override fun loadSdk(
+ sdkName: String,
+ params: Bundle,
+ executor: Executor,
+ callback: SdkSandboxControllerCompat.LoadSdkCallback
+ ) {
+ sdkLoader.loadSdk(sdkName, params, executor, callback)
+ }
override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
return controller
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/java/androidx/privacysandbox/tools/apigenerator/CallbacksApiGeneratorDiffTest.kt b/privacysandbox/tools/tools-apigenerator/src/test/java/androidx/privacysandbox/tools/apigenerator/CallbacksApiGeneratorDiffTest.kt
index 7907500..2398d20 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/java/androidx/privacysandbox/tools/apigenerator/CallbacksApiGeneratorDiffTest.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/java/androidx/privacysandbox/tools/apigenerator/CallbacksApiGeneratorDiffTest.kt
@@ -27,6 +27,7 @@
"com/sdkwithcallbacks/ISdkCallback.java",
"com/sdkwithcallbacks/ISdkService.java",
"com/sdkwithcallbacks/ParcelableResponse.java",
+ "com/sdkwithcallbacks/ParcelableMyEnum.java",
"com/sdkwithcallbacks/IMyUiInterface.java",
"com/sdkwithcallbacks/IMyUiInterfaceCoreLibInfoAndBinderWrapper.java"
)
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/input/com/sdkwithcallbacks/SdkService.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/input/com/sdkwithcallbacks/SdkService.kt
index 5c45597..5c2718b 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/input/com/sdkwithcallbacks/SdkService.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/input/com/sdkwithcallbacks/SdkService.kt
@@ -26,7 +26,10 @@
}
@PrivacySandboxValue
-data class Response(val response: String, val uiInterface: MyUiInterface)
+data class Response(val response: String, val uiInterface: MyUiInterface, val myEnum: MyEnum)
+
+@PrivacySandboxValue
+enum class MyEnum { FLIP, FLOP }
@PrivacySandboxInterface
interface MyInterface {
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyEnum.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyEnum.kt
new file mode 100644
index 0000000..1e0af70
--- /dev/null
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyEnum.kt
@@ -0,0 +1,6 @@
+package com.sdkwithcallbacks
+
+public enum class MyEnum {
+ FLIP,
+ FLOP,
+}
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyEnumConverter.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyEnumConverter.kt
new file mode 100644
index 0000000..9554eaf
--- /dev/null
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/MyEnumConverter.kt
@@ -0,0 +1,12 @@
+package com.sdkwithcallbacks
+
+public object MyEnumConverter {
+ public fun fromParcelable(parcelable: ParcelableMyEnum): MyEnum =
+ MyEnum.entries[parcelable.variant_ordinal]
+
+ public fun toParcelable(annotatedValue: MyEnum): ParcelableMyEnum {
+ val parcelable = ParcelableMyEnum()
+ parcelable.variant_ordinal = annotatedValue.ordinal
+ return parcelable
+ }
+}
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/Response.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/Response.kt
index a449083..752bbeb 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/Response.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/Response.kt
@@ -3,4 +3,5 @@
public data class Response(
public val response: String,
public val uiInterface: MyUiInterface,
+ public val myEnum: MyEnum,
)
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/ResponseConverter.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/ResponseConverter.kt
index e5105f8..4a42a82 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/ResponseConverter.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/ResponseConverter.kt
@@ -5,7 +5,8 @@
val annotatedValue = Response(
response = parcelable.response,
uiInterface = MyUiInterfaceClientProxy(parcelable.uiInterface.binder,
- parcelable.uiInterface.coreLibInfo))
+ parcelable.uiInterface.coreLibInfo),
+ myEnum = com.sdkwithcallbacks.MyEnumConverter.fromParcelable(parcelable.myEnum))
return annotatedValue
}
@@ -15,6 +16,7 @@
parcelable.uiInterface =
IMyUiInterfaceCoreLibInfoAndBinderWrapperConverter.toParcelable((annotatedValue.uiInterface
as MyUiInterfaceClientProxy).coreLibInfo, annotatedValue.uiInterface.remote)
+ parcelable.myEnum = com.sdkwithcallbacks.MyEnumConverter.toParcelable(annotatedValue.myEnum)
return parcelable
}
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
index 3d98913c..aad4cc0 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/test/MultiInstanceInvalidationTest.java
@@ -120,6 +120,8 @@
}
}
+ // TODO(324609478): broken test
+ @Ignore
@Test
public void invalidateInAnotherInstance() throws Exception {
final SampleDatabase db1 = openDatabase(true);
@@ -134,6 +136,8 @@
assertTrue(changed1.await(3, TimeUnit.SECONDS));
}
+ // TODO(324274513): broken test
+ @Ignore
@Test
public void invalidateInAnotherInstanceFts() throws Exception {
final SampleFtsDatabase db1 = openFtsDatabase(true);
diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle
index 7972af6..88190e2 100644
--- a/room/room-runtime/build.gradle
+++ b/room/room-runtime/build.gradle
@@ -33,6 +33,7 @@
id("AndroidXPlugin")
id("com.android.library")
id("androidx.stableaidl")
+ id("com.google.devtools.ksp")
}
def nativeEnabled = KmpPlatformsKt.enableNative(project)
@@ -196,6 +197,11 @@
dependencies {
lintChecks(project(":room:room-runtime-lint"))
sqliteSharedArchive(project(":sqlite:sqlite-bundled"))
+ add("kspAndroidAndroidTest", project(path: ":room:room-compiler", configuration: "shadowAndImplementation"))
+}
+
+ksp {
+ arg("room.generateKotlin", "true")
}
androidx {
diff --git a/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/MultiInstanceInvalidationTest.kt b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/MultiInstanceInvalidationTest.kt
new file mode 100644
index 0000000..36c22ac
--- /dev/null
+++ b/room/room-runtime/src/androidInstrumentedTest/kotlin/androidx/room/MultiInstanceInvalidationTest.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.room
+
+import android.app.ActivityManager
+import android.content.Context
+import android.os.Build
+import androidx.kruth.assertThat
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.test.Test
+import org.junit.Before
+
+class MultiInstanceInvalidationTest {
+ @Entity
+ data class SampleEntity(
+ @PrimaryKey
+ val pk: Int
+ )
+
+ @Database(
+ entities = [SampleEntity::class],
+ version = 1,
+ exportSchema = false
+ )
+ abstract class SampleDatabase : RoomDatabase()
+
+ private lateinit var autoCloseDb: SampleDatabase
+
+ @Suppress("DEPRECATION") // For `getRunningServices()`
+ @Test
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+ fun invalidateInAnotherInstanceAutoCloser() {
+ val latch = CountDownLatch(1)
+ val context = ApplicationProvider.getApplicationContext<Context>()
+ val manager = context.getSystemService(
+ ActivityManager::class.java
+ )
+ val autoCloseHelper = autoCloseDb.openHelper as AutoClosingRoomOpenHelper
+ val autoCloser = autoCloseHelper.autoCloser
+ autoCloseHelper.writableDatabase
+ // Make sure the service is running.
+ assertThat(manager.getRunningServices(100)).isNotEmpty()
+
+ // Let Room call setAutoCloseCallback
+ val trackerCallback = autoCloser.onAutoCloseCallback
+ autoCloser.setAutoCloseCallback {
+ trackerCallback?.run()
+ // At this point in time InvalidationTracker's callback has run and unbind should have
+ // been invoked.
+ latch.countDown()
+ }
+ latch.await()
+
+ // Make sure the service is no longer running.
+ assertThat(manager.getRunningServices(100)).isEmpty()
+ autoCloseDb.close()
+ }
+
+ @OptIn(ExperimentalRoomApi::class)
+ @Before
+ fun initDb() {
+ val context: Context = ApplicationProvider.getApplicationContext()
+ autoCloseDb = Room.databaseBuilder(
+ context,
+ SampleDatabase::class.java,
+ "MyDb"
+ )
+ .enableMultiInstanceInvalidation()
+ .setAutoCloseTimeout(200, TimeUnit.MILLISECONDS)
+ .build()
+ }
+}
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt
index c1192db..be39682 100644
--- a/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/InvalidationTracker.android.kt
@@ -88,6 +88,9 @@
private val trackerLock = Any()
+ /** The initialization state for restarting invalidation after auto-close. */
+ private var multiInstanceClientInitState: MultiInstanceClientInitState? = null
+
init {
tableIdLookup = mutableMapOf()
tablesNames = Array(tableNames.size) { id ->
@@ -161,6 +164,11 @@
return
}
+ multiInstanceClientInitState?.let {
+ // Start multi-instance invalidation, based in info from the saved initState.
+ startMultiInstanceInvalidation()
+ }
+
// These actions are not in a transaction because temp_store is not allowed to be
// performed on a transaction, and recursive_triggers is not affected by transactions.
database.execSQL("PRAGMA temp_store = MEMORY;")
@@ -174,27 +182,28 @@
private fun onAutoCloseCallback() {
synchronized(trackerLock) {
+ val isObserverMapEmpty = observerMap.filterNot { it.key.isRemote }.isEmpty()
+ if (multiInstanceInvalidationClient != null && isObserverMapEmpty) {
+ stopMultiInstanceInvalidation()
+ }
initialized = false
observedTableTracker.resetTriggerState()
cleanupStatement?.close()
}
}
- internal fun startMultiInstanceInvalidation(
- context: Context,
- name: String,
- serviceIntent: Intent
- ) {
+ private fun startMultiInstanceInvalidation() {
+ val state = checkNotNull(multiInstanceClientInitState)
multiInstanceInvalidationClient = MultiInstanceInvalidationClient(
- context = context,
- name = name,
- serviceIntent = serviceIntent,
+ context = state.context,
+ name = state.name,
+ serviceIntent = state.serviceIntent,
invalidationTracker = this,
executor = database.queryExecutor
)
}
- internal fun stopMultiInstanceInvalidation() {
+ private fun stopMultiInstanceInvalidation() {
multiInstanceInvalidationClient?.stop()
multiInstanceInvalidationClient = null
}
@@ -582,6 +591,22 @@
)
}
+ internal fun initMultiInstanceInvalidation(
+ context: Context,
+ name: String,
+ serviceIntent: Intent
+ ) {
+ multiInstanceClientInitState = MultiInstanceClientInitState(
+ context = context,
+ name = name,
+ serviceIntent = serviceIntent
+ )
+ }
+
+ internal fun stop() {
+ stopMultiInstanceInvalidation()
+ }
+
/**
* Wraps an observer and keeps the table information.
*
@@ -844,3 +869,12 @@
}
}
}
+
+/**
+ * Stores needed info to restart the invalidation after it was auto-closed.
+ */
+internal data class MultiInstanceClientInitState(
+ val context: Context,
+ val name: String,
+ val serviceIntent: Intent
+)
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
index 6d22589..450ae01 100644
--- a/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
+++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/RoomDatabase.android.kt
@@ -250,7 +250,7 @@
// Configure multi-instance invalidation, if enabled
if (configuration.multiInstanceInvalidationServiceIntent != null) {
requireNotNull(configuration.name)
- invalidationTracker.startMultiInstanceInvalidation(
+ invalidationTracker.initMultiInstanceInvalidation(
configuration.context,
configuration.name,
configuration.multiInstanceInvalidationServiceIntent
@@ -517,7 +517,7 @@
val closeLock: Lock = readWriteLock.writeLock()
closeLock.lock()
try {
- invalidationTracker.stopMultiInstanceInvalidation()
+ invalidationTracker.stop()
connectionManager.close()
} finally {
closeLock.unlock()
diff --git a/samples/MediaRoutingDemo/lint-baseline.xml b/samples/MediaRoutingDemo/lint-baseline.xml
index 020dd5f..c274efc 100644
--- a/samples/MediaRoutingDemo/lint-baseline.xml
+++ b/samples/MediaRoutingDemo/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="RestrictedApiAndroidX"
@@ -12,15 +12,6 @@
<issue
id="RestrictedApiAndroidX"
- message="RouteInfo.DEVICE_TYPE_BLUETOOTH can only be accessed from within the same library (androidx.mediarouter:mediarouter)"
- errorLine1=" BLUETOOTH(MediaRouter.RouteInfo.DEVICE_TYPE_BLUETOOTH),"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/com/example/androidx/mediarouting/data/RouteItem.java"/>
- </issue>
-
- <issue
- id="RestrictedApiAndroidX"
message="RouteInfo.DEVICE_TYPE_UNKNOWN can only be accessed from within the same library (androidx.mediarouter:mediarouter)"
errorLine1=" UNKNOWN(MediaRouter.RouteInfo.DEVICE_TYPE_UNKNOWN);"
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
diff --git a/settings.gradle b/settings.gradle
index 21bbb5a..7c7abd3 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -509,11 +509,13 @@
includeProject(":compose:lint:common", [BuildType.COMPOSE])
includeProject(":compose:lint:common-test", [BuildType.COMPOSE])
includeProject(":compose:material", [BuildType.COMPOSE])
+includeProject(":compose:material3:adaptive:adaptive", [BuildType.COMPOSE])
+includeProject(":compose:material3:adaptive:adaptive-layout", [BuildType.COMPOSE])
+includeProject(":compose:material3:adaptive:adaptive-navigation", [BuildType.COMPOSE])
+includeProject(":compose:material3:adaptive:adaptive-samples", "compose/material3/adaptive/samples", [BuildType.COMPOSE])
+includeProject(":compose:material3:adaptive:adaptive-benchmark", "compose/material3/adaptive/benchmark", [BuildType.COMPOSE])
includeProject(":compose:material3:material3", [BuildType.COMPOSE])
includeProject(":compose:material3:benchmark", [BuildType.COMPOSE])
-includeProject(":compose:material3:material3-adaptive", [BuildType.COMPOSE])
-includeProject(":compose:material3:material3-adaptive:material3-adaptive-samples", "compose/material3/material3-adaptive/samples", [BuildType.COMPOSE])
-includeProject(":compose:material3:material3-adaptive:material3-adaptive-benchmark", "compose/material3/material3-adaptive/benchmark", [BuildType.COMPOSE])
includeProject(":compose:material3:material3-adaptive-navigation-suite", [BuildType.COMPOSE])
includeProject(":compose:material3:material3-adaptive-navigation-suite:material3-adaptive-navigation-suite-samples", "compose/material3/material3-adaptive-navigation-suite/samples", [BuildType.COMPOSE])
includeProject(":compose:material3:material3-common", [BuildType.COMPOSE])
@@ -1111,7 +1113,6 @@
includeProject(":internal-testutils-macrobenchmark", "testutils/testutils-macrobenchmark", [BuildType.MAIN, BuildType.COMPOSE])
includeProject(":internal-testutils-navigation", "testutils/testutils-navigation", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
includeProject(":internal-testutils-paging", "testutils/testutils-paging", [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":internal-testutils-paparazzi", "testutils/testutils-paparazzi", [BuildType.COMPOSE])
includeProject(":internal-testutils-gradle-plugin", "testutils/testutils-gradle-plugin", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE, BuildType.TOOLS])
includeProject(":internal-testutils-mockito", "testutils/testutils-mockito", [BuildType.MAIN, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE])
includeProject(":kruth:kruth", [BuildType.MAIN, BuildType.INFRAROGUE, BuildType.KMP, BuildType.COMPOSE])
@@ -1144,8 +1145,6 @@
includeProject(":external:libyuv", [BuildType.CAMERA])
includeProject(":noto-emoji-compat-font", new File(externalRoot, "noto-fonts/emoji-compat"), [BuildType.MAIN])
includeProject(":noto-emoji-compat-flatbuffers", new File(externalRoot, "noto-fonts/emoji-compat-flatbuffers"), [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":external:paparazzi:paparazzi", [BuildType.COMPOSE])
-includeProject(":external:paparazzi:paparazzi-agent", [BuildType.COMPOSE])
if (isAllProjects()) {
includeProject(":docs-tip-of-tree")
diff --git a/stableaidl/stableaidl-gradle-plugin/lint-baseline.xml b/stableaidl/stableaidl-gradle-plugin/lint-baseline.xml
deleted file mode 100644
index aec53bc..0000000
--- a/stableaidl/stableaidl-gradle-plugin/lint-baseline.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
- errorLine1=" val incoming = project.configurations.findByName("${variant.name}CompileClasspath")?.incoming"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/stableaidl/StableAidlPlugin.kt"/>
- </issue>
-
- <issue
- id="EagerGradleConfiguration"
- message="Avoid using eager method findByName"
- errorLine1=" project.configurations.findByName(targetConfig)?.outgoing?.variants { variants ->"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="src/main/java/androidx/stableaidl/StableAidlTasks.kt"/>
- </issue>
-
-</issues>
diff --git a/testutils/testutils-paparazzi/build.gradle b/testutils/testutils-paparazzi/build.gradle
deleted file mode 100644
index 68d62b0..0000000
--- a/testutils/testutils-paparazzi/build.gradle
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2022 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.
- */
-
-/**
- * This file was created using the `create_project.py` script located in the
- * `<AndroidX root>/development/project-creator` directory.
- *
- * Please use that script when creating a new project, rather than copying an existing project and
- * modifying its settings.
- */
-import androidx.build.BundleInsideHelper
-import androidx.build.LibraryType
-
-plugins {
- id("AndroidXPlugin")
- id("kotlin")
-}
-
-BundleInsideHelper.forInsideJar(
- project,
- "com.google.protobuf",
- // b/268288856 untangle this mess.
- // Currently this has to match test/screenshot/screenshot/build.gradle because sometimes
- // both :internal-testutils-paparazzi and :test:screenshot:screenshot are added to the
- // classpath and picking a different package will cause missing class exceptions due to
- // class shadowing
- "androidx.test.screenshot.protobuf",
- // proto-lite dependency includes .proto files, which are not used and would clash if
- // users also use proto library directly
- /* dropResourcesWithSuffix = */ ".proto"
-)
-
-dependencies {
- api(project(":external:paparazzi:paparazzi"))
- bundleInside(project(path: ":test:screenshot:screenshot-proto"))
-
- testImplementation(libs.junit)
- testImplementation(libs.kotlinTestJunit)
-}
-
-androidx {
- type = LibraryType.INTERNAL_HOST_TEST_LIBRARY
-}
\ No newline at end of file
diff --git a/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/AndroidXPaparazzi.kt b/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/AndroidXPaparazzi.kt
deleted file mode 100644
index 510b7f2..0000000
--- a/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/AndroidXPaparazzi.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.testutils.paparazzi
-
-import app.cash.paparazzi.DeviceConfig
-import app.cash.paparazzi.Environment
-import app.cash.paparazzi.Paparazzi
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode
-import java.io.File
-
-/**
- * Creates a [Paparazzi] test rule configured from system properties for AndroidX tests with the
- * `AndroidXPaparazziPlugin` Gradle plugin applied.
- *
- * Golden images used with this framework are expected to have a one-to-one relationship to test
- * functions. This helps ensure isolation between test functions and facilitates updating golden
- * images programmatically via the `:updateGolden` Gradle task or CI.
- *
- * To this end, golden images are named by the qualified name of their test function, instead of
- * a secondary identifier. Additionally, the returned [Paparazzi] instance will enforce a limit of
- * one snapshot per test function.
- */
-fun androidxPaparazzi(
- deviceConfig: DeviceConfig = DeviceConfig.PIXEL_6.copy(softButtons = false),
- theme: String = "android:Theme.Material.NoActionBar.Fullscreen",
- renderingMode: RenderingMode = RenderingMode.SHRINK,
- imageDiffer: ImageDiffer = ImageDiffer.MSSIMMatcher
-) = Paparazzi(
- deviceConfig = deviceConfig,
- theme = theme,
- renderingMode = renderingMode,
- environment = Environment(
- platformDir = systemProperty("platformDir"),
- resDir = systemProperty("resDir"),
- assetsDir = systemProperty("assetsDir"),
- compileSdkVersion = systemProperty("compileSdkVersion").toInt(),
- resourcePackageNames = systemProperty("resourcePackageNames").split(","),
- appTestDir = System.getProperty("user.dir")!!
- ),
- snapshotHandler = GoldenVerifier(
- modulePath = systemProperty("modulePath"),
- goldenRootDirectory = File(systemProperty("goldenRootDir")),
- reportDirectory = File(systemProperty("reportDir")),
- imageDiffer = imageDiffer
- )
-)
-
-/** Package name used for resolving system properties */
-internal const val PACKAGE_NAME = "androidx.testutils.paparazzi"
-
-/** Name of the internal Gradle plugin */
-private const val PLUGIN_NAME = "AndroidXPaparazziPlugin"
-
-/** Name of the module containing this library */
-private const val MODULE_NAME = ":internal-testutils-paparazzi"
-
-/** Read a system property with [PACKAGE_NAME] prefix, throwing an exception if missing */
-private fun systemProperty(name: String) = checkNotNull(System.getProperty("$PACKAGE_NAME.$name")) {
- if (System.getProperty("$PACKAGE_NAME.gradlePluginApplied").toBoolean()) {
- "Missing required system property: $PACKAGE_NAME.$name. This is likely due to version " +
- "mismatch between $PLUGIN_NAME and $MODULE_NAME."
- } else {
- "Paparazzi system properties not set. Please ensure $PLUGIN_NAME is applied to your build."
- }
-}
diff --git a/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/GoldenVerifier.kt b/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/GoldenVerifier.kt
deleted file mode 100644
index 8282bd9d..0000000
--- a/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/GoldenVerifier.kt
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.testutils.paparazzi
-
-import androidx.test.screenshot.proto.ScreenshotResultProto.ScreenshotResult
-import androidx.test.screenshot.proto.ScreenshotResultProto.ScreenshotResult.Status
-import app.cash.paparazzi.Snapshot
-import app.cash.paparazzi.SnapshotHandler
-import app.cash.paparazzi.TestName
-import java.awt.image.BufferedImage
-import java.io.File
-import javax.imageio.ImageIO
-
-/**
- * This [SnapshotHandler] implements AndroidX-specific logic for screenshot testing. Specifically,
- * it writes a report to [reportDirectory] at every comparison just before throwing an exception,
- * even on successful comparison. The report contains text and binary protos containing the status
- * of the comparison and relative paths to actual, expected (copy of golden), and difference
- * (magenta highlights) images as applicable. CI consumes these reports to allow updating golden
- * images from the web UI. Golden images can also be updated by the `:updateGolden` Gradle task,
- * which copies actual images to their expected location in the golden repo.
- *
- * It also knows that the AndroidX golden repo, located at [goldenRootDirectory], is partitioned
- * by Gradle project path or [modulePath] and loads images from it.
- *
- * As noted in documentation on [androidxPaparazzi], the verifier is the component to enforce a
- * one-to-one relationship between test functions and golden images. This isn't strictly necessary,
- * but CI currently expects reports to be generated as a side effect of a regular test invocation.
- * Enforcing a one-to-one relationship avoids a situation where a failing assertion earlier in the
- * test would stop a later assertion from executing and generating its report as a side effect,
- * requiring multiple rounds of updating golden images to get the test passing.
- *
- * Additionally, CI currently only supports one comparison per report (note the [ScreenshotResult]
- * proto is not repeated). If this limit is lifted in the future, we would need to devise a scheme
- * for naming additional golden images such as an index of the order they were invoked and wrap the
- * test rule with something like an `ErrorCollector` to ensure later assertions are always
- * reachable.
- *
- * @property modulePath Unique path for the module, derived from Gradle project path. The verifier
- * will search for golden images in this directory relative to [goldenRootDirectory].
- *
- * @property goldenRootDirectory Location on disk of the golden images repo. Golden images for this
- * module are found in the [modulePath] directory under this directory.
- *
- * @property reportDirectory Directory to write reports, including protos, actual and expected
- * images, and image diffs.
- *
- * @property imageDiffer An [ImageDiffer] for comparing images.
- *
- * @property goldenRepoName Name of the repo containing golden images. Used for CI
- */
-internal class GoldenVerifier(
- val modulePath: String,
- val goldenRootDirectory: File,
- val reportDirectory: File,
- val imageDiffer: ImageDiffer = ImageDiffer.PixelPerfect,
- val goldenRepoName: String = ANDROIDX_GOLDEN_REPO_NAME
-) : SnapshotHandler {
- /** Directory containing golden images for this module. */
- val goldenDirectory = goldenRootDirectory.resolve(modulePath)
-
- /** The set of tests seen by this verifier, used to enforce single assertion per test. */
- private val attemptedTests = mutableSetOf<TestName>()
-
- /**
- * Asserts that the [actual] matches the expected golden for the test described in [snapshot].
- * As a side effect, this writes the report proto, actual, expected, and difference images to
- * [reportDirectory] as appropriate.
- */
- fun assertMatchesGolden(snapshot: Snapshot, actual: BufferedImage) {
- check(snapshot.testName !in attemptedTests) {
- "Snapshot already taken for test \"${snapshot.testName.methodName}\". Taking " +
- "multiple snapshots per test is not currently supported."
- }
- attemptedTests += snapshot.testName
-
- val expected = snapshot.toGoldenFile().takeIf { it.canRead() }?.let { ImageIO.read(it) }
- val analysis = analyze(expected, actual)
-
- fun updateMessage() = "To update golden images for this test module, run " +
- "${updateGoldenGradleCommand()}."
-
- writeReport(snapshot, analysis)
-
- when (analysis) {
- is AnalysisResult.Passed -> { /** Test passed, don't need to throw anything */ }
- is AnalysisResult.Failed -> throw AssertionError(
- "Actual image differs from golden image: ${analysis.imageDiff.description}. " +
- updateMessage()
- )
- is AnalysisResult.SizeMismatch -> throw AssertionError(
- "Actual image has different dimensions than golden image. " +
- "Actual: ${analysis.actual.width}x${analysis.actual.height}. " +
- "Golden: ${analysis.expected.width}x${analysis.expected.height}. " +
- updateMessage()
- )
- is AnalysisResult.MissingGolden -> throw AssertionError(
- "Expected golden image for test \"${snapshot.testName.methodName}\" does not " +
- "exist. Run ${updateGoldenGradleCommand()} " +
- "to create it and update all golden images for this test module."
- )
- }
- }
-
- /** Compare [expected] golden image to [actual] image and return an [AnalysisResult] */
- fun analyze(expected: BufferedImage?, actual: BufferedImage): AnalysisResult {
- if (expected == null) {
- return AnalysisResult.MissingGolden(actual)
- }
-
- if (actual.width != expected.width || actual.height != expected.height) {
- return AnalysisResult.SizeMismatch(actual, expected)
- }
-
- return when (val diff = imageDiffer.diff(actual, expected)) {
- is ImageDiffer.DiffResult.Similar -> AnalysisResult.Passed(actual, expected, diff)
- is ImageDiffer.DiffResult.Different -> AnalysisResult.Failed(actual, expected, diff)
- }
- }
-
- /**
- * Write the [analysis] for test described by [snapshot] to [reportDirectory] as both binary
- * and text proto, including actual, expected, and difference image files as appropriate.
- */
- fun writeReport(snapshot: Snapshot, analysis: AnalysisResult) {
- val actualFile = snapshot.toActualFile().also { ImageIO.write(analysis.actual, "PNG", it) }
- val goldenFile = snapshot.toGoldenFile()
-
- val resultProto = ScreenshotResult.newBuilder().apply {
- currentScreenshotFileName = actualFile.toRelativeString(reportDirectory)
- repoRootPath = goldenRepoName
- locationOfGoldenInRepo = goldenFile.toRelativeString(goldenRootDirectory)
- }
-
- fun diffFile(diff: BufferedImage) = snapshot.toDiffFile()
- .also { ImageIO.write(diff, "PNG", it) }
- .toRelativeString(reportDirectory)
-
- fun expectedFile() = goldenFile.copyTo(snapshot.toExpectedFile())
- .toRelativeString(reportDirectory)
-
- when (analysis) {
- is AnalysisResult.Passed -> resultProto.apply {
- result = Status.PASSED
- expectedImageFileName = expectedFile()
- analysis.imageDiff.highlights?.let { diffImageFileName = diffFile(it) }
- comparisonStatistics = analysis.imageDiff.taggedDescription()
- }
- is AnalysisResult.Failed -> resultProto.apply {
- result = Status.FAILED
- expectedImageFileName = expectedFile()
- diffImageFileName = diffFile(analysis.imageDiff.highlights)
- comparisonStatistics = analysis.imageDiff.taggedDescription()
- }
- is AnalysisResult.SizeMismatch -> resultProto.apply {
- result = Status.SIZE_MISMATCH
- expectedImageFileName = expectedFile()
- }
- is AnalysisResult.MissingGolden -> resultProto.apply {
- result = Status.MISSING_GOLDEN
- }
- }
-
- val result = resultProto.build()
- snapshot.toResultProtoFile().outputStream().use { result.writeTo(it) }
-
- // TODO(b/244200590): Remove text proto output, or replace with JSON
- snapshot.toResultTextProtoFile().writeText(result.toString())
- }
-
- /**
- * Analysis result ADT returned from [analyze], including actual and expected images and
- * an [ImageDiffer.DiffResult].
- */
- sealed interface AnalysisResult {
- val actual: BufferedImage
-
- data class Passed(
- override val actual: BufferedImage,
- val expected: BufferedImage,
- val imageDiff: ImageDiffer.DiffResult.Similar
- ) : AnalysisResult
-
- data class Failed(
- override val actual: BufferedImage,
- val expected: BufferedImage,
- val imageDiff: ImageDiffer.DiffResult.Different
- ) : AnalysisResult
-
- data class SizeMismatch(
- override val actual: BufferedImage,
- val expected: BufferedImage
- ) : AnalysisResult
-
- data class MissingGolden(
- override val actual: BufferedImage
- ) : AnalysisResult
- }
-
- override fun newFrameHandler(
- snapshot: Snapshot,
- frameCount: Int,
- fps: Int
- ): SnapshotHandler.FrameHandler {
- require(frameCount == 1) { "Videos are not yet supported" }
-
- return object : SnapshotHandler.FrameHandler {
- override fun handle(image: BufferedImage) {
- assertMatchesGolden(snapshot, image)
- }
-
- override fun close() = Unit
- }
- }
-
- override fun close() = Unit
-
- /** Adds [ImageDiffer.name] as a prefix to [ImageDiffer.DiffResult.description]. */
- private fun ImageDiffer.DiffResult.taggedDescription() =
- "[${imageDiffer.name}]: $description"
-
- // Filename templates based for a given snapshot
- private fun Snapshot.toGoldenFile() = goldenDirectory.resolve("${toFileName()}_paparazzi.png")
- private fun Snapshot.toExpectedFile() = reportDirectory.resolve("${toFileName()}_expected.png")
- private fun Snapshot.toActualFile() = reportDirectory.resolve("${toFileName()}_actual.png")
- private fun Snapshot.toDiffFile() = reportDirectory.resolve("${toFileName()}_diff.png")
- private fun Snapshot.toResultProtoFile() =
- reportDirectory.resolve("${toFileName()}_goldResult.pb")
- private fun Snapshot.toResultTextProtoFile() =
- reportDirectory.resolve("${toFileName()}_goldResult.textproto")
-
- companion object {
- /** Name of the AndroidX golden repo. */
- const val ANDROIDX_GOLDEN_REPO_NAME = "platform/frameworks/support-golden"
-
- /** Name of the updateGolden Gradle command for this module, via system properties. */
- fun updateGoldenGradleCommand() =
- "./gradlew ${
- (System.getProperty("$PACKAGE_NAME.updateGoldenTask") ?: ":updateGolden")
- } -Pandroidx.ignoreTestFailures=true"
-
- /** Render test function name as a fully qualified string. */
- fun TestName.toQualifiedName(): String {
- return if (packageName.isEmpty()) {
- "$className.$methodName"
- } else {
- "$packageName.$className.$methodName"
- }
- }
-
- /** Get a file name with special characters removed from a snapshot. */
- fun Snapshot.toFileName() = testName.toQualifiedName().replace(Regex("\\W+"), "_")
- }
-}
diff --git a/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/ImageDiffer.kt b/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/ImageDiffer.kt
deleted file mode 100644
index 8902cb4..0000000
--- a/testutils/testutils-paparazzi/src/main/kotlin/androidx/testutils/paparazzi/ImageDiffer.kt
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.testutils.paparazzi
-
-import androidx.testutils.paparazzi.ImageDiffer.DiffResult.Similar
-import java.awt.image.BufferedImage
-import kotlin.math.pow
-
-@JvmDefaultWithCompatibility
-/**
- * Functional interface to compare two images and returns a [ImageDiffer.DiffResult] ADT containing
- * comparison statistics and a difference image, if applicable.
- */
-fun interface ImageDiffer {
- /**
- * Compare image [a] to image [b]. Implementations may assume [a] and [b] have the same
- * dimensions.
- */
- fun diff(a: BufferedImage, b: BufferedImage): DiffResult
-
- /** A name to be used in logs for this differ, defaulting to the class's simple name. */
- val name
- get() = requireNotNull(this::class.simpleName) {
- "Could not determine ImageDiffer.name reflectively. Please override ImageDiffer.name."
- }
-
- /**
- * Result ADT returned from [diff].
- *
- * A differ may permit a small amount of difference, even for [Similar] results. Similar results
- * must include a [description], even if it's trivial, but may omit the [highlights] image if
- * it would be fully transparent.
- *
- * @property description A human-readable description of how the images differed, such as the
- * count of different pixels or percentage changed. Displayed in test failure messages and in
- * CI.
- *
- * @property highlights An image with a transparent background, highlighting where the compared
- * images differ, typically in shades of magenta. Displayed in CI.
- */
- sealed interface DiffResult {
- val description: String
- val highlights: BufferedImage?
-
- data class Similar(
- override val description: String,
- override val highlights: BufferedImage? = null
- ) : DiffResult
-
- data class Different(
- override val description: String,
- override val highlights: BufferedImage
- ) : DiffResult
- }
-
- /**
- * Pixel perfect image differ requiring images to be identical.
- *
- * The alpha channel is treated as pre-multiplied, meaning RGB channels may differ if the alpha
- * channel is 0 (fully transparent).
- */
- // TODO(b/244752233): Support wide gamut images.
- object PixelPerfect : ImageDiffer {
- override fun diff(a: BufferedImage, b: BufferedImage): DiffResult {
- check(a.width == b.width && a.height == b.height) { "Images are different sizes" }
- val width = a.width
- val height = b.height
- val highlights = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
- var count = 0
-
- for (x in 0 until width) {
- for (y in 0 until height) {
- val aPixel = a.getRGB(x, y)
- val bPixel = b.getRGB(x, y)
-
- // Compare full ARGB pixels, but allow other channels to differ if alpha is 0
- if (aPixel == bPixel || (aPixel ushr 24 == 0 && bPixel ushr 24 == 0)) {
- highlights.setRGB(x, y, TRANSPARENT.toInt())
- } else {
- count++
- highlights.setRGB(x, y, MAGENTA.toInt())
- }
- }
- }
-
- val description = "$count of ${width * height} pixels different"
- return if (count > 0) {
- DiffResult.Different(description, highlights)
- } else {
- DiffResult.Similar(description)
- }
- }
- }
-
- /**
- * Image comparison using Structural Similarity Index, developed by Wang, Bovik, Sheikh, and
- * Simoncelli. Details can be read in their paper:
- * https://ece.uwaterloo.ca/~z70wang/publications/ssim.pdf
- */
- object MSSIMMatcher : ImageDiffer {
- override fun diff(a: BufferedImage, b: BufferedImage): DiffResult {
- val aIntArray = a.toIntArray()
- val bIntArray = b.toIntArray()
- val SSIMTotal = calculateSSIM(aIntArray, bIntArray, a.width, a.height)
-
- val stats = "[MSSIM] Required SSIM: $SSIM_THRESHOLD, Actual " +
- "SSIM: " + "%.3f".format(SSIMTotal)
- if (SSIMTotal >= SSIM_THRESHOLD) {
- return DiffResult.Similar(stats)
- }
- return PixelPerfect.diff(a, b)
- }
-
- internal fun calculateSSIM(
- ideal: IntArray,
- given: IntArray,
- width: Int,
- height: Int
- ): Double {
- return calculateSSIM(ideal, given, 0, width, width, height)
- }
-
- private fun calculateSSIM(
- ideal: IntArray,
- given: IntArray,
- offset: Int,
- stride: Int,
- width: Int,
- height: Int
- ): Double {
- var SSIMTotal = 0.0
- var windows = 0
- var currentWindowY = 0
- while (currentWindowY < height) {
- val windowHeight = computeWindowSize(currentWindowY, height)
- var currentWindowX = 0
- while (currentWindowX < width) {
- val windowWidth = computeWindowSize(currentWindowX, width)
- val start: Int =
- indexFromXAndY(currentWindowX, currentWindowY, stride, offset)
- if (isWindowWhite(ideal, start, stride, windowWidth, windowHeight) &&
- isWindowWhite(given, start, stride, windowWidth, windowHeight)
- ) {
- currentWindowX += WINDOW_SIZE
- continue
- }
- windows++
- val means =
- getMeans(ideal, given, start, stride, windowWidth, windowHeight)
- val meanX = means[0]
- val meanY = means[1]
- val variances = getVariances(
- ideal, given, meanX, meanY, start, stride,
- windowWidth, windowHeight
- )
- val varX = variances[0]
- val varY = variances[1]
- val stdBoth = variances[2]
- val SSIM = SSIM(meanX, meanY, varX, varY, stdBoth)
- SSIMTotal += SSIM
- currentWindowX += WINDOW_SIZE
- }
- currentWindowY += WINDOW_SIZE
- }
- if (windows == 0) {
- return 1.0
- }
- return SSIMTotal / windows.toDouble()
- }
-
- /**
- * Compute the size of the window. The window defaults to WINDOW_SIZE, but
- * must be contained within dimension.
- */
- private fun computeWindowSize(coordinateStart: Int, dimension: Int): Int {
- return if (coordinateStart + WINDOW_SIZE <= dimension) {
- WINDOW_SIZE
- } else {
- dimension - coordinateStart
- }
- }
-
- private fun isWindowWhite(
- colors: IntArray,
- start: Int,
- stride: Int,
- windowWidth: Int,
- windowHeight: Int
- ): Boolean {
- for (y in 0 until windowHeight) {
- for (x in 0 until windowWidth) {
- if (colors[indexFromXAndY(x, y, stride, start)] != WHITE) {
- return false
- }
- }
- }
- return true
- }
-
- /**
- * This calculates the position in an array that would represent a bitmap given the parameters.
- */
- private fun indexFromXAndY(x: Int, y: Int, stride: Int, offset: Int): Int {
- return x + y * stride + offset
- }
-
- private fun SSIM(
- muX: Double,
- muY: Double,
- sigX: Double,
- sigY: Double,
- sigXY: Double
- ): Double {
- var SSIM = (2 * muX * muY + CONSTANT_C1) * (2 * sigXY + CONSTANT_C2)
- val denom = ((muX * muX + muY * muY + CONSTANT_C1) * (sigX + sigY + CONSTANT_C2))
- SSIM /= denom
- return SSIM
- }
-
- /**
- * This method will find the mean of a window in both sets of pixels. The return is an array
- * where the first double is the mean of the first set and the second double is the mean of the
- * second set.
- */
- private fun getMeans(
- pixels0: IntArray,
- pixels1: IntArray,
- start: Int,
- stride: Int,
- windowWidth: Int,
- windowHeight: Int
- ): DoubleArray {
- var avg0 = 0.0
- var avg1 = 0.0
- for (y in 0 until windowHeight) {
- for (x in 0 until windowWidth) {
- val index: Int = indexFromXAndY(x, y, stride, start)
- avg0 += getIntensity(pixels0[index])
- avg1 += getIntensity(pixels1[index])
- }
- }
- avg0 /= windowWidth * windowHeight.toDouble()
- avg1 /= windowWidth * windowHeight.toDouble()
- return doubleArrayOf(avg0, avg1)
- }
-
- /**
- * Finds the variance of the two sets of pixels, as well as the covariance of the windows. The
- * return value is an array of doubles, the first is the variance of the first set of pixels,
- * the second is the variance of the second set of pixels, and the third is the covariance.
- */
- private fun getVariances(
- pixels0: IntArray,
- pixels1: IntArray,
- mean0: Double,
- mean1: Double,
- start: Int,
- stride: Int,
- windowWidth: Int,
- windowHeight: Int
- ): DoubleArray {
- if (windowHeight == 1 && windowWidth == 1) {
- // There is only one item. The variance of a single item would be 0.
- // Since Bessel's correction is used below, it will return NaN instead of 0.
- return doubleArrayOf(0.0, 0.0, 0.0)
- }
-
- var var0 = 0.0
- var var1 = 0.0
- var varBoth = 0.0
- for (y in 0 until windowHeight) {
- for (x in 0 until windowWidth) {
- val index: Int = indexFromXAndY(x, y, stride, start)
- val v0 = getIntensity(pixels0[index]) - mean0
- val v1 = getIntensity(pixels1[index]) - mean1
- var0 += v0 * v0
- var1 += v1 * v1
- varBoth += v0 * v1
- }
- }
- // Using Bessel's correction. Hence, subtracting one.
- val denominatorWithBesselsCorrection = windowWidth * windowHeight - 1.0
- var0 /= denominatorWithBesselsCorrection
- var1 /= denominatorWithBesselsCorrection
- varBoth /= denominatorWithBesselsCorrection
- return doubleArrayOf(var0, var1, varBoth)
- }
-
- /**
- * Gets the intensity of a given pixel in RGB using luminosity formula
- *
- * l = 0.21R' + 0.72G' + 0.07B'
- *
- * The prime symbols dictate a gamma correction of 1.
- */
- private fun getIntensity(pixel: Int): Double {
- val gamma = 1.0
- var l = 0.0
- l += 0.21f * (red(pixel) / 255f.toDouble()).pow(gamma)
- l += 0.72f * (green(pixel) / 255f.toDouble()).pow(gamma)
- l += 0.07f * (blue(pixel) / 255f.toDouble()).pow(gamma)
- return l
- }
-
- /**
- * Return the red component of a color int. This is the same as saying
- * (color >> 16) & 0xFF
- */
- fun red(color: Int): Int {
- return color shr 16 and 0xFF
- }
-
- /**
- * Return the green component of a color int. This is the same as saying
- * (color >> 8) & 0xFF
- */
- fun green(color: Int): Int {
- return color shr 8 and 0xFF
- }
-
- /**
- * Return the blue component of a color int. This is the same as saying
- * color & 0xFF
- */
- fun blue(color: Int): Int {
- return color and 0xFF
- }
-
- private fun BufferedImage.toIntArray(): IntArray {
- val bitmapArray = IntArray(width * height)
- for (x in 0 until width) {
- for (y in 0 until height) {
- bitmapArray[y * width + x] = getRGB(x, y)
- }
- }
- return bitmapArray
- }
- }
-
- private companion object {
- const val MAGENTA = 0xFF_FF_00_FFu
- const val TRANSPARENT = 0x00_FF_FF_FFu
- const val WHITE = 0xFFFFFF
-
- // These values were taken from the publication
- private const val CONSTANT_L = 254.0
- private const val CONSTANT_K1 = 0.00001
- private const val CONSTANT_K2 = 0.00003
- private val CONSTANT_C1 = (CONSTANT_L * CONSTANT_K1).pow(2.0)
- private val CONSTANT_C2 = (CONSTANT_L * CONSTANT_K2).pow(2.0)
- private const val WINDOW_SIZE = 10
-
- private val SSIM_THRESHOLD: Double = 0.98
- }
-}
diff --git a/testutils/testutils-paparazzi/src/test/kotlin/androidx/testutils/paparazzi/GoldenVerifierTest.kt b/testutils/testutils-paparazzi/src/test/kotlin/androidx/testutils/paparazzi/GoldenVerifierTest.kt
deleted file mode 100644
index aee8a81..0000000
--- a/testutils/testutils-paparazzi/src/test/kotlin/androidx/testutils/paparazzi/GoldenVerifierTest.kt
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.testutils.paparazzi
-
-import androidx.test.screenshot.proto.ScreenshotResultProto.ScreenshotResult
-import androidx.test.screenshot.proto.ScreenshotResultProto.ScreenshotResult.Status
-import app.cash.paparazzi.Snapshot
-import java.awt.image.BufferedImage
-import java.io.File
-import java.util.Date
-import javax.imageio.ImageIO
-import kotlin.test.Test
-import kotlin.test.assertContains
-import kotlin.test.assertEquals
-import kotlin.test.assertFails
-import kotlin.test.assertFailsWith
-import kotlin.test.assertIs
-import org.junit.Rule
-import org.junit.rules.TemporaryFolder
-import org.junit.rules.TestName
-
-class GoldenVerifierTest {
- @get:Rule
- val testName = TestName()
-
- @get:Rule
- val goldenDirectory = TemporaryFolder()
-
- @get:Rule
- val reportDirectory = TemporaryFolder()
-
- private val modulePath = "testutils/testutils-paparazzi"
-
- @Test
- fun `snapshot handler success`() {
- createGolden("circle")
- goldenVerifier().newFrameHandler(snapshot(), 1, 0).handle(loadTestImage("circle"))
- }
-
- @Test
- fun `snapshot handler failure`() {
- createGolden("star")
- assertFails {
- goldenVerifier().newFrameHandler(snapshot(), 1, 0).handle(loadTestImage("circle"))
- }
- }
-
- @Test
- fun `removes special characters in file names`() {
- createGolden("circle")
- // Test that createGolden/goldenFile match naming in verifier
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle"))
-
- assertEquals(
- goldenFile().name,
- "androidx_testutils_paparazzi_GoldenVerifierTest_" +
- "removes_special_characters_in_file_names_paparazzi.png"
- )
- }
-
- @Test
- fun `writes report on success`() {
- createGolden("circle")
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle"))
-
- val proto = reportProto()
- assertEquals(Status.PASSED, proto.result)
- assertEquals(reportFile("expected.png").name, proto.expectedImageFileName)
- assertEquals("", proto.diffImageFileName)
- assertEquals("[PixelPerfect]: 0 of 65536 pixels different", proto.comparisonStatistics)
- assertContains(reportFile("goldResult.textproto").readText(), "PASSED")
- }
-
- @Test
- fun `writes actual image on success`() {
- createGolden("circle")
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle"))
- assertEquals(loadTestImage("circle"), reportFile("actual.png").readImage())
- }
-
- @Test
- fun `writes expected image on success`() {
- createGolden("circle")
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle"))
- assertEquals(loadTestImage("circle"), reportFile("expected.png").readImage())
- }
-
- @Test
- fun `analysis of success`() {
- val analysis = goldenVerifier().analyze(loadTestImage("circle"), loadTestImage("circle"))
- assertIs<GoldenVerifier.AnalysisResult.Passed>(analysis)
- assertEquals(loadTestImage("circle"), analysis.actual)
- assertEquals(loadTestImage("circle"), analysis.expected)
- }
-
- @Test
- fun `asserts on failure`() {
- createGolden("star")
- val message = "Actual image differs from golden image: 17837 of 65536 pixels different. " +
- "To update golden images for this test module, run ./gradlew :updateGolden " +
- "-Pandroidx.ignoreTestFailures=true."
-
- assertFailsWithMessage(message) {
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle"))
- }
- }
-
- @Test
- fun `writes result proto on failure`() {
- createGolden("star")
- assertFails { goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle")) }
-
- val proto = reportProto()
- assertEquals(Status.FAILED, proto.result)
- assertEquals(reportFile("expected.png").name, proto.expectedImageFileName)
- assertEquals(reportFile("diff.png").name, proto.diffImageFileName)
- assertEquals("[PixelPerfect]: 17837 of 65536 pixels different", proto.comparisonStatistics)
- assertContains(reportFile("goldResult.textproto").readText(), "FAILED")
- }
-
- @Test
- fun `writes actual image on failure`() {
- createGolden("star")
- assertFails { goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle")) }
- assertEquals(loadTestImage("circle"), reportFile("actual.png").readImage())
- }
-
- @Test
- fun `writes expected image on failure`() {
- createGolden("star")
- assertFails { goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle")) }
- assertEquals(loadTestImage("star"), reportFile("expected.png").readImage())
- }
-
- @Test
- fun `writes diff image on failure`() {
- createGolden("star")
- assertFails { goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle")) }
- assertEquals(loadTestImage("PixelPerfect_diff"), reportFile("diff.png").readImage())
- }
-
- @Test
- fun `analysis of failure`() {
- val analysis = goldenVerifier().analyze(loadTestImage("circle"), loadTestImage("star"))
- assertIs<GoldenVerifier.AnalysisResult.Failed>(analysis)
- assertEquals(loadTestImage("star"), analysis.actual)
- assertEquals(loadTestImage("circle"), analysis.expected)
- assertEquals(loadTestImage("PixelPerfect_diff"), analysis.imageDiff.highlights)
- }
-
- @Test
- fun `asserts on size mismatch`() {
- createGolden("horizontal_rectangle")
- val message = "Actual image has different dimensions than golden image. Actual: 72x128. " +
- "Golden: 128x72. To update golden images for this test module, run ./gradlew " +
- ":updateGolden -Pandroidx.ignoreTestFailures=true."
-
- assertFailsWithMessage(message) {
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("vertical_rectangle"))
- }
- }
-
- @Test
- fun `writes result proto for size mismatch`() {
- createGolden("horizontal_rectangle")
- assertFails {
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("vertical_rectangle"))
- }
-
- val proto = reportProto()
- assertEquals(Status.SIZE_MISMATCH, proto.result)
- assertEquals(reportFile("expected.png").name, proto.expectedImageFileName)
- assertEquals("", proto.diffImageFileName)
- assertEquals("", proto.comparisonStatistics)
- assertContains(reportFile("goldResult.textproto").readText(), "SIZE_MISMATCH")
- }
-
- @Test
- fun `writes actual image for size mismatch`() {
- createGolden("horizontal_rectangle")
- assertFails {
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("vertical_rectangle"))
- }
-
- assertEquals(loadTestImage("vertical_rectangle"), reportFile("actual.png").readImage())
- }
-
- @Test
- fun `writes expected image for size mismatch`() {
- createGolden("horizontal_rectangle")
- assertFails {
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("vertical_rectangle"))
- }
-
- assertEquals(loadTestImage("horizontal_rectangle"), reportFile("expected.png").readImage())
- }
-
- @Test
- fun `analysis of size mismatch`() {
- val analysis = goldenVerifier()
- .analyze(loadTestImage("horizontal_rectangle"), loadTestImage("vertical_rectangle"))
- assertIs<GoldenVerifier.AnalysisResult.SizeMismatch>(analysis)
- assertEquals(loadTestImage("vertical_rectangle"), analysis.actual)
- assertEquals(loadTestImage("horizontal_rectangle"), analysis.expected)
- }
-
- @Test
- fun `asserts on missing golden`() {
- val message = "Expected golden image for test \"asserts on missing golden\" does not " +
- "exist. Run ./gradlew :updateGolden -Pandroidx.ignoreTestFailures=true to create it " +
- "and update all golden images for this test module."
-
- assertFailsWithMessage(message) {
- goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle"))
- }
- }
-
- @Test
- fun `writes result proto for missing golden`() {
- assertFails { goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle")) }
-
- val proto = reportProto()
- assertEquals(Status.MISSING_GOLDEN, proto.result)
- assertEquals("", proto.expectedImageFileName)
- assertEquals("", proto.diffImageFileName)
- assertEquals("", proto.comparisonStatistics)
- assertContains(reportFile("goldResult.textproto").readText(), "MISSING_GOLDEN")
- }
-
- @Test
- fun `writes actual image for missing golden`() {
- assertFails { goldenVerifier().assertMatchesGolden(snapshot(), loadTestImage("circle")) }
- assertEquals(loadTestImage("circle"), reportFile("actual.png").readImage())
- }
-
- @Test
- fun `analysis of missing golden`() {
- val analysis = goldenVerifier().analyze(null, loadTestImage("circle"))
- assertIs<GoldenVerifier.AnalysisResult.MissingGolden>(analysis)
- assertEquals(loadTestImage("circle"), analysis.actual)
- }
-
- @Test
- fun `ensures single snapshot per method`() {
- val verifier = goldenVerifier()
- createGolden("circle")
-
- verifier.assertMatchesGolden(snapshot(), loadTestImage("circle"))
- assertFails { verifier.assertMatchesGolden(snapshot(), loadTestImage("circle")) }
- }
-
- private fun goldenVerifier() = GoldenVerifier(
- modulePath = modulePath,
- goldenRootDirectory = goldenDirectory.root,
- reportDirectory = reportDirectory.root
- )
-
- /** Assert [block] throws an [AssertionError] with supplied [message]. */
- private inline fun assertFailsWithMessage(message: String, block: () -> Unit) {
- assertEquals(message, assertFailsWith<AssertionError> { block() }.message)
- }
-
- /** Compare two images using [ImageDiffer.PixelPerfect]. */
- private fun assertEquals(expected: BufferedImage, actual: BufferedImage) {
- assertIs<ImageDiffer.DiffResult.Similar>(
- ImageDiffer.PixelPerfect.diff(expected, actual),
- message = "Expected images to be identical, but they were not."
- )
- }
-
- private fun snapshot() = Snapshot(
- name = null,
- testName = app.cash.paparazzi.TestName(
- packageName = this::class.java.packageName,
- className = this::class.simpleName!!,
- methodName = testName.methodName
- ),
- timestamp = Date()
- )
-
- /** Create a golden image for this test from the supplied test image [name]. */
- private fun createGolden(name: String) = javaClass.getResourceAsStream("$name.png")!!
- .copyTo(goldenFile().apply { parentFile!!.mkdirs() }.outputStream())
-
- /** Relative path to golden image for this test. */
- private fun goldenPath() = "$modulePath/${testName()}_paparazzi.png"
-
- /** Resolve the file path for a golden image for this test under [goldenDirectory]. */
- private fun goldenFile() = goldenDirectory.root.resolve(goldenPath()).canonicalFile
-
- /** Read the binary result proto under for this test and check common fields. */
- private fun reportProto() =
- ScreenshotResult.parseFrom(reportFile("goldResult.pb").inputStream()).also { proto ->
- assertEquals(reportFile("actual.png").name, proto.currentScreenshotFileName)
- assertEquals(GoldenVerifier.ANDROIDX_GOLDEN_REPO_NAME, proto.repoRootPath)
- assertEquals(goldenPath(), proto.locationOfGoldenInRepo)
- }
-
- /** Resolve the file path for a report file with provided [suffix] under [reportDirectory]. */
- private fun reportFile(suffix: String) =
- reportDirectory.root.resolve("${testName()}_$suffix").canonicalFile
-
- /** Convenience function to read an image from a file. */
- private fun File.readImage() = ImageIO.read(this)
-
- /** Fully qualified test ID with special characters replaced for this test. */
- private fun testName() = "${this::class.qualifiedName!!}_${testName.methodName}"
- .replace(Regex("\\W+"), "_")
-
- /** Load a test image from resources. */
- private fun loadTestImage(name: String) =
- ImageIO.read(javaClass.getResourceAsStream("$name.png")!!)
-}
diff --git a/testutils/testutils-paparazzi/src/test/kotlin/androidx/testutils/paparazzi/ImageDifferTest.kt b/testutils/testutils-paparazzi/src/test/kotlin/androidx/testutils/paparazzi/ImageDifferTest.kt
deleted file mode 100644
index 8b67607..0000000
--- a/testutils/testutils-paparazzi/src/test/kotlin/androidx/testutils/paparazzi/ImageDifferTest.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.testutils.paparazzi
-
-import androidx.testutils.paparazzi.ImageDiffer.DiffResult.Different
-import androidx.testutils.paparazzi.ImageDiffer.DiffResult.Similar
-import androidx.testutils.paparazzi.ImageDiffer.PixelPerfect
-import javax.imageio.ImageIO
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertIs
-import kotlin.test.assertNull
-
-class ImageDifferTest {
- @Test
- fun `PixelPerfect similar`() {
- val result = PixelPerfect.diff(loadTestImage("circle"), loadTestImage("circle"))
- assertIs<Similar>(result)
- assertEquals("0 of 65536 pixels different", result.description)
- assertNull(result.highlights)
- }
-
- @Test
- fun `PixelPerfect different`() {
- val result = PixelPerfect.diff(loadTestImage("circle"), loadTestImage("star"))
- assertIs<Different>(result)
- assertEquals("17837 of 65536 pixels different", result.description)
- assertIs<Similar>(
- PixelPerfect.diff(result.highlights, loadTestImage("PixelPerfect_diff"))
- )
- }
-
- @Test
- fun `PixelPerfect name`() {
- assertEquals("PixelPerfect", PixelPerfect.name)
- }
-
- private fun loadTestImage(name: String) =
- ImageIO.read(javaClass.getResourceAsStream("$name.png")!!)
-}
diff --git a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/PixelPerfect_diff.png b/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/PixelPerfect_diff.png
deleted file mode 100644
index 8e3b7b8..0000000
--- a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/PixelPerfect_diff.png
+++ /dev/null
Binary files differ
diff --git a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/circle.png b/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/circle.png
deleted file mode 100644
index e6d58321..0000000
--- a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/circle.png
+++ /dev/null
Binary files differ
diff --git a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/horizontal_rectangle.png b/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/horizontal_rectangle.png
deleted file mode 100644
index a13221a..0000000
--- a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/horizontal_rectangle.png
+++ /dev/null
Binary files differ
diff --git a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/star.png b/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/star.png
deleted file mode 100644
index 61b0c64..0000000
--- a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/star.png
+++ /dev/null
Binary files differ
diff --git a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/vertical_rectangle.png b/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/vertical_rectangle.png
deleted file mode 100644
index 91a607e..0000000
--- a/testutils/testutils-paparazzi/src/test/resources/androidx/testutils/paparazzi/vertical_rectangle.png
+++ /dev/null
Binary files differ
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
index 1857244..ff46bd7 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
@@ -53,6 +53,7 @@
@OptIn(ExperimentalFoundationApi::class)
@ExperimentalTvFoundationApi
+@Suppress("DEPRECATION")
fun Modifier.scrollableWithPivot(
state: ScrollableState,
orientation: Orientation,
diff --git a/vectordrawable/integration-tests/testapp/lint-baseline.xml b/vectordrawable/integration-tests/testapp/lint-baseline.xml
index b35bd65..3e6d21b 100644
--- a/vectordrawable/integration-tests/testapp/lint-baseline.xml
+++ b/vectordrawable/integration-tests/testapp/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="NewApi"
@@ -121,8 +121,8 @@
<issue
id="InvalidVectorPath"
message="Use -0.001 instead of -.001 to avoid crashes on some devices"
- errorLine1=" M 3.65, 6.125"
- errorLine2=" ~~~~~">
+ errorLine1=" m-.001, 0"
+ errorLine2=" ~~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
@@ -130,8 +130,8 @@
<issue
id="InvalidVectorPath"
message="Use 0.001 instead of .001 to avoid crashes on some devices"
- errorLine1=" m-.001, 0"
- errorLine2=" ~~~~">
+ errorLine1=" a .001,.001 0 1,0 .002,0"
+ errorLine2=" ~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
@@ -139,8 +139,8 @@
<issue
id="InvalidVectorPath"
message="Use 0.001 instead of .001 to avoid crashes on some devices"
- errorLine1=" m-.001, 0"
- errorLine2=" ~~~~">
+ errorLine1=" a .001,.001 0 1,0 .002,0"
+ errorLine2=" ~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
@@ -148,8 +148,8 @@
<issue
id="InvalidVectorPath"
message="Use 0.002 instead of .002 to avoid crashes on some devices"
- errorLine1=" m-.001, 0"
- errorLine2=" ^">
+ errorLine1=" a .001,.001 0 1,0 .002,0"
+ errorLine2=" ~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
@@ -157,8 +157,8 @@
<issue
id="InvalidVectorPath"
message="Use -0.002 instead of -.002 to avoid crashes on some devices"
- errorLine1=" a .001,.001 0 1,0 .002,0"
- errorLine2=" ^">
+ errorLine1=" a .001,.001 0 1,0-.002,0z" />"
+ errorLine2=" ~~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
@@ -166,8 +166,8 @@
<issue
id="InvalidVectorPath"
message="Use 0.001 instead of .001 to avoid crashes on some devices"
- errorLine1=" a .001,.001 0 1,0 .002,0"
- errorLine2=" ~~~~">
+ errorLine1=" a .001,.001 0 1,0-.002,0z" />"
+ errorLine2=" ~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
@@ -175,8 +175,8 @@
<issue
id="InvalidVectorPath"
message="Use 0.001 instead of .001 to avoid crashes on some devices"
- errorLine1=" a .001,.001 0 1,0 .002,0"
- errorLine2=" ~~~~">
+ errorLine1=" a .001,.001 0 1,0-.002,0z" />"
+ errorLine2=" ~~~~">
<location
file="src/main/res/drawable/vector_drawable04.xml"/>
</issue>
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Placeholder.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Placeholder.kt
index 4cb7df0..81cba40 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Placeholder.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Placeholder.kt
@@ -394,7 +394,7 @@
* @param shape the shape to apply to the placeholder
* @param color the color of the placeholder.
*/
-@Suppress("ComposableModifierFactory")
+@Suppress("ComposableModifierFactory", "DEPRECATION")
@ExperimentalWearMaterialApi
@Composable
public fun Modifier.placeholder(
@@ -445,7 +445,7 @@
* @param color the color to use in the shimmer.
*/
-@Suppress("ComposableModifierFactory")
+@Suppress("ComposableModifierFactory", "DEPRECATION")
@ExperimentalWearMaterialApi
@OptIn(ExperimentalWearFoundationApi::class)
@Composable
diff --git a/wear/compose/integration-tests/demos/build.gradle b/wear/compose/integration-tests/demos/build.gradle
index c2f20c3..912149c 100644
--- a/wear/compose/integration-tests/demos/build.gradle
+++ b/wear/compose/integration-tests/demos/build.gradle
@@ -68,6 +68,7 @@
androidTestImplementation(project(":activity:activity"))
androidTestImplementation(project(":activity:activity-compose"))
androidTestImplementation(project(":activity:activity-ktx"))
+ androidTestImplementation(project(":compose:runtime:runtime"))
androidTestImplementation(project(":compose:ui:ui-test-junit4"))
androidTestImplementation("androidx.lifecycle:lifecycle-runtime:2.7.0")
androidTestImplementation("androidx.lifecycle:lifecycle-common:2.7.0")
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstance.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstance.java
index 5f95a07..b8482ca 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstance.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstance.java
@@ -970,7 +970,11 @@
int gravity = UNSPECIFIED_GRAVITY;
LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
- if (prevInflateParent != null && prevInflateParent.getChildCount() > 0) {
+ if (prevInflateParent != null
+ && prevInflateParent.getChildCount() > 0
+ // This is to ensure we are centering the correct parent and that it wasn't
+ // changed after previous inflation.
+ && prevRenderedMetadata != null) {
View firstChild = prevInflateParent.getChildAt(0);
if (firstChild != null) {
FrameLayout.LayoutParams childLp =
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstanceTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstanceTest.java
index 1571b81..6db2dfb 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstanceTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/impl/ProtoLayoutViewInstanceTest.java
@@ -46,6 +46,7 @@
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -194,6 +195,57 @@
}
@Test
+ public void rootContainerChangeChild_beforeLayoutUpdate_layoutReinflates() throws Exception {
+ setupInstance(/* adaptiveUpdateRatesEnabled= */ true);
+
+ // Render the first layout.
+ Layout layout1 = layout(column(dynamicFixedText(TEXT1), dynamicFixedText(TEXT2)));
+ ListenableFuture<Void> result =
+ mInstanceUnderTest.renderAndAttach(
+ layout1, RESOURCES, mRootContainer);
+ shadowOf(Looper.getMainLooper()).idle();
+
+ assertNoException(result);
+
+ List<View> textView1 = findViewsWithText(mRootContainer, TEXT1);
+ assertThat(textView1).hasSize(1);
+ assertThat(findViewsWithText(mRootContainer, TEXT2)).hasSize(1);
+
+ // Change child to a layout that doesn't have FrameLayout.LayoutParams.
+ // This tests that the new layout will be correctly inflated and that there is no exception
+ // thrown when LayoutParams are not as expected (FrameLayout.LayoutParams).
+
+ RelativeLayout newParent = new RelativeLayout(mApplicationContext);
+ newParent.setLayoutParams(new RelativeLayout.LayoutParams(100, 100));
+ // Setting a child is necessary to trigger centering with LayoutParams.
+ newParent.addView(new RelativeLayout(mApplicationContext));
+
+ mRootContainer.removeAllViews();
+ mRootContainer.addView(newParent);
+
+ // Now renderer the new layout. In regular case this would be partial update, but here the
+ // not changed part of the layout was also changed in inflated View.
+ Layout layout2 = layout(column(dynamicFixedText(TEXT1), dynamicFixedText(TEXT3)));
+
+ result =
+ mInstanceUnderTest.renderAndAttach(
+ layout2, RESOURCES, mRootContainer);
+
+ // Make sure future is computing result.
+ assertThat(result.isDone()).isFalse();
+ shadowOf(Looper.getMainLooper()).idle();
+
+ assertNoException(result);
+
+ // Everything should be re-inflated.
+ List<View> updatedTextView1 = findViewsWithText(mRootContainer, TEXT1);
+ assertThat(updatedTextView1).hasSize(1);
+ assertThat(updatedTextView1.get(0)).isNotEqualTo(textView1.get(0));
+ assertThat(findViewsWithText(mRootContainer, TEXT2)).isEmpty();
+ assertThat(findViewsWithText(mRootContainer, TEXT3)).isNotEmpty();
+ }
+
+ @Test
public void adaptiveUpdateRatesEnabled_attach_withDynamicValue_appliesDiffOnly()
throws Exception {
setupInstance(/* adaptiveUpdateRatesEnabled= */ true);
diff --git a/wear/watchface/watchface-style/lint-baseline.xml b/wear/watchface/watchface-style/lint-baseline.xml
deleted file mode 100644
index 4e453d5..0000000
--- a/wear/watchface/watchface-style/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.2.0-alpha14" type="baseline" client="cli" dependencies="false" name="AGP (8.2.0-alpha14)" variant="all" version="8.2.0-alpha14">
-
- <issue
- id="NewApi"
- message="Class requires API level 33 (current min is 26): `LargeCustomValueUserStyleSetting`"
- errorLine1=" is UserStyleSetting.LargeCustomValueUserStyleSetting ->"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/wear/watchface/style/CurrentUserStyleRepository.kt"/>
- </issue>
-
-</issues>
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt
index 3fdbecb..147d2a9 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt
@@ -239,6 +239,7 @@
0,
0,
mConfiguration.executor,
+ mConfiguration.workerCoroutineContext,
mTaskExecutor,
mConfiguration.workerFactory,
progressUpdater,
diff --git a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableWorkerParameters.java b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableWorkerParameters.java
index cdfda32f..5aa72cc 100644
--- a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableWorkerParameters.java
+++ b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/parcelable/ParcelableWorkerParameters.java
@@ -185,6 +185,7 @@
mRunAttemptCount,
mGeneration,
configuration.getExecutor(),
+ configuration.getWorkerCoroutineContext(),
taskExecutor,
configuration.getWorkerFactory(),
progressUpdater,
diff --git a/work/work-runtime/api/current.txt b/work/work-runtime/api/current.txt
index 6d1f114..452cc68 100644
--- a/work/work-runtime/api/current.txt
+++ b/work/work-runtime/api/current.txt
@@ -29,6 +29,7 @@
method public androidx.work.RunnableScheduler getRunnableScheduler();
method public androidx.core.util.Consumer<java.lang.Throwable>? getSchedulingExceptionHandler();
method public java.util.concurrent.Executor getTaskExecutor();
+ method public kotlin.coroutines.CoroutineContext getWorkerCoroutineContext();
method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerExecutionExceptionHandler();
method public androidx.work.WorkerFactory getWorkerFactory();
method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerInitializationExceptionHandler();
@@ -43,6 +44,7 @@
property public final androidx.work.RunnableScheduler runnableScheduler;
property public final androidx.core.util.Consumer<java.lang.Throwable>? schedulingExceptionHandler;
property public final java.util.concurrent.Executor taskExecutor;
+ property public final kotlin.coroutines.CoroutineContext workerCoroutineContext;
property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerExecutionExceptionHandler;
property public final androidx.work.WorkerFactory workerFactory;
property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerInitializationExceptionHandler;
@@ -65,6 +67,7 @@
method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler runnableScheduler);
method public androidx.work.Configuration.Builder setSchedulingExceptionHandler(androidx.core.util.Consumer<java.lang.Throwable> schedulingExceptionHandler);
method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor taskExecutor);
+ method public androidx.work.Configuration.Builder setWorkerCoroutineContext(kotlinx.coroutines.CoroutineDispatcher dispatcher);
method public androidx.work.Configuration.Builder setWorkerExecutionExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory workerFactory);
method public androidx.work.Configuration.Builder setWorkerInitializationExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
diff --git a/work/work-runtime/api/restricted_current.txt b/work/work-runtime/api/restricted_current.txt
index 6d1f114..452cc68 100644
--- a/work/work-runtime/api/restricted_current.txt
+++ b/work/work-runtime/api/restricted_current.txt
@@ -29,6 +29,7 @@
method public androidx.work.RunnableScheduler getRunnableScheduler();
method public androidx.core.util.Consumer<java.lang.Throwable>? getSchedulingExceptionHandler();
method public java.util.concurrent.Executor getTaskExecutor();
+ method public kotlin.coroutines.CoroutineContext getWorkerCoroutineContext();
method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerExecutionExceptionHandler();
method public androidx.work.WorkerFactory getWorkerFactory();
method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerInitializationExceptionHandler();
@@ -43,6 +44,7 @@
property public final androidx.work.RunnableScheduler runnableScheduler;
property public final androidx.core.util.Consumer<java.lang.Throwable>? schedulingExceptionHandler;
property public final java.util.concurrent.Executor taskExecutor;
+ property public final kotlin.coroutines.CoroutineContext workerCoroutineContext;
property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerExecutionExceptionHandler;
property public final androidx.work.WorkerFactory workerFactory;
property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerInitializationExceptionHandler;
@@ -65,6 +67,7 @@
method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler runnableScheduler);
method public androidx.work.Configuration.Builder setSchedulingExceptionHandler(androidx.core.util.Consumer<java.lang.Throwable> schedulingExceptionHandler);
method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor taskExecutor);
+ method public androidx.work.Configuration.Builder setWorkerCoroutineContext(kotlinx.coroutines.CoroutineDispatcher dispatcher);
method public androidx.work.Configuration.Builder setWorkerExecutionExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory workerFactory);
method public androidx.work.Configuration.Builder setWorkerInitializationExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
diff --git a/work/work-runtime/lint-baseline.xml b/work/work-runtime/lint-baseline.xml
index e57c7ec..d7d9e69 100644
--- a/work/work-runtime/lint-baseline.xml
+++ b/work/work-runtime/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-beta01)" variant="all" version="8.3.0-beta01">
+<issues format="6" by="lint 8.4.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0-alpha07)" variant="all" version="8.4.0-alpha07">
<issue
id="BanSynchronizedMethods"
@@ -13,42 +13,6 @@
<issue
id="BanThreadSleep"
message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(TEST_TIMEOUT_IN_MS);"
- errorLine2=" ~~~~~">
- <location
- file="src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(TEST_TIMEOUT_IN_MS);"
- errorLine2=" ~~~~~">
- <location
- file="src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(TEST_TIMEOUT_IN_MS);"
- errorLine2=" ~~~~~">
- <location
- file="src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(TEST_TIMEOUT_IN_MS);"
- errorLine2=" ~~~~~">
- <location
- file="src/androidTest/java/androidx/work/impl/workers/ConstraintTrackingWorkerTest.java"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
errorLine1=" Thread.sleep(duration);"
errorLine2=" ~~~~~">
<location
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/ConfigurationExecutorsTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/ConfigurationExecutorsTest.kt
new file mode 100644
index 0000000..40e6d54
--- /dev/null
+++ b/work/work-runtime/src/androidTest/java/androidx/work/ConfigurationExecutorsTest.kt
@@ -0,0 +1,209 @@
+/*
+ * 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.work
+
+import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.work.impl.WorkManagerImpl
+import androidx.work.impl.constraints.trackers.Trackers
+import androidx.work.impl.testutils.TrackingWorkerFactory
+import androidx.work.testutils.GreedyScheduler
+import androidx.work.testutils.TestEnv
+import androidx.work.testutils.WorkManager
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executors
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.asExecutor
+import kotlinx.coroutines.currentCoroutineContext
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+class ConfigurationExecutorsTest {
+ val workerFactory = TrackingWorkerFactory()
+ val executor = Executors.newSingleThreadExecutor {
+ Thread(it).also { thread -> thread.name = threadTestName }
+ }
+
+ @Test
+ fun testSetExecutor() = runBlocking {
+ val configuration = Configuration.Builder()
+ .setWorkerFactory(workerFactory)
+ .setExecutor(executor)
+ .build()
+ val env = TestEnv(configuration)
+ val trackers = Trackers(context = env.context, taskExecutor = env.taskExecutor)
+ val workManager = WorkManager(env, listOf(GreedyScheduler(env, trackers)), trackers)
+ WorkManagerImpl.setDelegate(workManager)
+
+ val blockingRequest = OneTimeWorkRequest.from(ThreadNameWorker::class.java)
+ workManager.enqueue(blockingRequest)
+ val blockingWorker = workerFactory.await(blockingRequest.id) as ThreadNameWorker
+ assertThat(blockingWorker.threadNameDeferred.await()).isEqualTo(threadTestName)
+
+ val coroutineRequest = OneTimeWorkRequest.from(CoroutineDispatcherWorker::class.java)
+ workManager.enqueue(coroutineRequest)
+ val coroutineWorker = workerFactory.await(coroutineRequest.id) as CoroutineDispatcherWorker
+
+ val coroutineDispatcher = coroutineWorker.coroutineDispatcherDeferred.await()
+ assertThat(coroutineDispatcher?.asExecutor()).isEqualTo(executor)
+ }
+
+ @Test
+ fun testSetWorkerCoroutineDispatcher() = runBlocking {
+ val dispatcher = executor.asCoroutineDispatcher()
+ val configuration = Configuration.Builder()
+ .setWorkerFactory(workerFactory)
+ .setWorkerCoroutineContext(dispatcher)
+ .build()
+ val env = TestEnv(configuration)
+ val trackers = Trackers(context = env.context, taskExecutor = env.taskExecutor)
+ val workManager = WorkManager(env, listOf(GreedyScheduler(env, trackers)), trackers)
+ WorkManagerImpl.setDelegate(workManager)
+
+ val blockingRequest = OneTimeWorkRequest.from(ThreadNameWorker::class.java)
+ workManager.enqueue(blockingRequest)
+ val blockingWorker = workerFactory.await(blockingRequest.id) as ThreadNameWorker
+ assertThat(blockingWorker.threadNameDeferred.await()).isEqualTo(threadTestName)
+
+ val coroutineRequest = OneTimeWorkRequest.from(CoroutineDispatcherWorker::class.java)
+ workManager.enqueue(coroutineRequest)
+ val coroutineWorker = workerFactory.await(coroutineRequest.id) as CoroutineDispatcherWorker
+
+ val coroutineDispatcher = coroutineWorker.coroutineDispatcherDeferred.await()
+ assertThat(coroutineDispatcher).isEqualTo(dispatcher)
+ }
+
+ @Test
+ fun testSetBoth() = runBlocking {
+ val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
+ val configuration = Configuration.Builder()
+ .setWorkerFactory(workerFactory)
+ .setExecutor(executor)
+ .setWorkerCoroutineContext(dispatcher)
+ .build()
+ val env = TestEnv(configuration)
+ val trackers = Trackers(context = env.context, taskExecutor = env.taskExecutor)
+ val workManager = WorkManager(env, listOf(GreedyScheduler(env, trackers)), trackers)
+ WorkManagerImpl.setDelegate(workManager)
+
+ val blockingRequest = OneTimeWorkRequest.from(ThreadNameWorker::class.java)
+ workManager.enqueue(blockingRequest)
+ val blockingWorker = workerFactory.await(blockingRequest.id) as ThreadNameWorker
+ assertThat(blockingWorker.threadNameDeferred.await()).isEqualTo(threadTestName)
+
+ val coroutineRequest = OneTimeWorkRequest.from(CoroutineDispatcherWorker::class.java)
+ workManager.enqueue(coroutineRequest)
+ val coroutineWorker = workerFactory.await(coroutineRequest.id) as CoroutineDispatcherWorker
+
+ val coroutineDispatcher = coroutineWorker.coroutineDispatcherDeferred.await()
+ assertThat(coroutineDispatcher).isEqualTo(dispatcher)
+ }
+
+ @Test
+ fun testSetNeither() = runBlocking {
+ val configuration = Configuration.Builder()
+ .setWorkerFactory(workerFactory)
+ .build()
+ val env = TestEnv(configuration)
+ val trackers = Trackers(context = env.context, taskExecutor = env.taskExecutor)
+ val workManager = WorkManager(env, listOf(GreedyScheduler(env, trackers)), trackers)
+ WorkManagerImpl.setDelegate(workManager)
+
+ val coroutineRequest = OneTimeWorkRequest.from(CoroutineDispatcherWorker::class.java)
+ workManager.enqueue(coroutineRequest)
+ val coroutineWorker = workerFactory.await(coroutineRequest.id) as CoroutineDispatcherWorker
+
+ val coroutineDispatcher = coroutineWorker.coroutineDispatcherDeferred.await()
+ assertThat(coroutineDispatcher).isEqualTo(Dispatchers.Default)
+ }
+
+ @Test
+ fun testSetCoroutineContextOverride() = runBlocking {
+ val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
+ val configuration = Configuration.Builder()
+ .setWorkerFactory(workerFactory)
+ .setExecutor(executor)
+ .setWorkerCoroutineContext(dispatcher)
+ .build()
+ val env = TestEnv(configuration)
+ val trackers = Trackers(context = env.context, taskExecutor = env.taskExecutor)
+ val workManager = WorkManager(env, listOf(GreedyScheduler(env, trackers)), trackers)
+ WorkManagerImpl.setDelegate(workManager)
+
+ val coroutineRequest = OneTimeWorkRequest.from(CoroutineContextOverridingWorker::class.java)
+ workManager.enqueue(coroutineRequest)
+ val coroutineWorker = workerFactory.await(coroutineRequest.id)
+ as CoroutineContextOverridingWorker
+
+ val coroutineDispatcher = coroutineWorker.coroutineDispatcherDeferred.await()
+ @Suppress("DEPRECATION")
+ assertThat(coroutineDispatcher).isEqualTo(coroutineWorker.coroutineContext)
+ }
+}
+
+private const val threadTestName = "configuration_test"
+
+class ThreadNameWorker(
+ context: Context,
+ workerParams: WorkerParameters
+) : Worker(context, workerParams) {
+ val threadNameDeferred = CompletableDeferred<String>()
+
+ override fun doWork(): Result {
+ threadNameDeferred.complete(Thread.currentThread().name)
+ return Result.success()
+ }
+}
+
+class CoroutineDispatcherWorker(
+ appContext: Context,
+ params: WorkerParameters
+) : CoroutineWorker(appContext, params) {
+ val coroutineDispatcherDeferred = CompletableDeferred<CoroutineDispatcher?>()
+
+ @OptIn(ExperimentalStdlibApi::class)
+ override suspend fun doWork(): Result {
+ coroutineDispatcherDeferred.complete(currentCoroutineContext()[CoroutineDispatcher])
+ return Result.success()
+ }
+}
+
+class CoroutineContextOverridingWorker(
+ appContext: Context,
+ params: WorkerParameters,
+) : CoroutineWorker(appContext, params) {
+ private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
+
+ @Suppress("OVERRIDE_DEPRECATION")
+ override val coroutineContext: CoroutineDispatcher
+ get() = dispatcher
+
+ val coroutineDispatcherDeferred = CompletableDeferred<CoroutineDispatcher?>()
+
+ @OptIn(ExperimentalStdlibApi::class)
+ override suspend fun doWork(): Result {
+ coroutineDispatcherDeferred.complete(currentCoroutineContext()[CoroutineDispatcher])
+ return Result.success()
+ }
+}
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java b/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java
index 20c26d7..cd18321 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java
@@ -39,6 +39,8 @@
import java.util.concurrent.Executor;
+import kotlinx.coroutines.Dispatchers;
+
@RunWith(AndroidJUnit4.class)
public class DefaultWorkerFactoryTest extends DatabaseTest {
@@ -73,6 +75,7 @@
1,
0,
executor,
+ Dispatchers.getDefault(),
new WorkManagerTaskExecutor(executor),
mDefaultWorkerFactory,
mProgressUpdater,
@@ -101,6 +104,7 @@
1,
0,
executor,
+ Dispatchers.getDefault(),
new WorkManagerTaskExecutor(executor),
mDefaultWorkerFactory,
mProgressUpdater,
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt
index 29ce8c5..bc03195 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt
@@ -25,6 +25,7 @@
import androidx.work.worker.FailureWorker
import androidx.work.worker.TestWorker
import java.util.UUID
+import kotlinx.coroutines.Dispatchers
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.MatcherAssert.assertThat
@@ -98,6 +99,7 @@
1,
0,
SynchronousExecutor(),
+ Dispatchers.Default,
WorkManagerTaskExecutor(SynchronousExecutor()),
factory,
progressUpdater,
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt
index 3794ddb..9a680b7 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt
@@ -34,6 +34,7 @@
import com.google.common.util.concurrent.ListenableFuture
import java.util.UUID
import java.util.concurrent.Executor
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Assert.fail
import org.junit.Before
@@ -168,6 +169,7 @@
1,
0,
executor,
+ Dispatchers.Default,
taskExecutor,
configuration.workerFactory,
progressUpdater,
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
index ddb9e31..8510b51 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
@@ -114,6 +114,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import kotlinx.coroutines.Dispatchers;
+
@RunWith(AndroidJUnit4.class)
public class WorkerWrapperTest extends DatabaseTest {
@@ -230,6 +232,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1007,6 +1010,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1036,6 +1040,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1056,6 +1061,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1085,6 +1091,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1115,6 +1122,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1149,6 +1157,7 @@
1,
0,
mSynchronousExecutor,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
@@ -1397,6 +1406,7 @@
1,
0,
executorService,
+ Dispatchers.getDefault(),
mWorkTaskExecutor,
mConfiguration.getWorkerFactory(),
mMockProgressUpdater,
diff --git a/work/work-runtime/src/main/java/androidx/work/Configuration.kt b/work/work-runtime/src/main/java/androidx/work/Configuration.kt
index ddcbc4d..8f33b1d 100644
--- a/work/work-runtime/src/main/java/androidx/work/Configuration.kt
+++ b/work/work-runtime/src/main/java/androidx/work/Configuration.kt
@@ -27,8 +27,14 @@
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicInteger
+import kotlin.coroutines.ContinuationInterceptor
+import kotlin.coroutines.CoroutineContext
import kotlin.math.max
import kotlin.math.min
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.asExecutor
/**
* The Configuration object used to customize [WorkManager] upon initialization.
@@ -44,6 +50,11 @@
val executor: Executor
/**
+ * The [CoroutineContext] used by [WorkManager] to execute [CoroutineWorker]s.
+ */
+ val workerCoroutineContext: CoroutineContext
+
+ /**
* The [Executor] used by [WorkManager] for all its internal business logic
*/
val taskExecutor: Executor
@@ -150,7 +161,19 @@
val isUsingDefaultTaskExecutor: Boolean
init {
- executor = builder.executor ?: createDefaultExecutor(isTaskExecutor = false)
+ val builderWorkerDispatcher = builder.workerContext
+
+ executor = builder.executor ?: builderWorkerDispatcher?.asExecutor()
+ ?: createDefaultExecutor(isTaskExecutor = false)
+
+ workerCoroutineContext = when {
+ builderWorkerDispatcher != null -> builderWorkerDispatcher
+ // we don't want simply always use executor.asCoroutineDispatcher()
+ // as compatibility measure
+ builder.executor != null -> executor.asCoroutineDispatcher()
+ else -> Dispatchers.Default
+ }
+
isUsingDefaultTaskExecutor = builder.taskExecutor == null
// This executor is used for *both* WorkManager's tasks and Room's query executor.
// So this should not be a single threaded executor. Writes will still be serialized
@@ -182,6 +205,7 @@
*/
class Builder {
internal var executor: Executor? = null
+ internal var workerContext: CoroutineContext? = null
internal var workerFactory: WorkerFactory? = null
internal var inputMergerFactory: InputMergerFactory? = null
internal var taskExecutor: Executor? = null
@@ -226,7 +250,7 @@
initializationExceptionHandler = configuration.initializationExceptionHandler
schedulingExceptionHandler = configuration.schedulingExceptionHandler
workerInitializationExceptionHandler =
- configuration.workerInitializationExceptionHandler
+ configuration.workerInitializationExceptionHandler
workerExecutionExceptionHandler = configuration.workerExecutionExceptionHandler
defaultProcessName = configuration.defaultProcessName
}
@@ -254,7 +278,10 @@
}
/**
- * Specifies a custom [Executor] for WorkManager.
+ * Specifies a custom [Executor] to run [Worker.doWork].
+ *
+ * If [setWorkerCoroutineContext] wasn't called then the [executor] will be used as
+ * [CoroutineDispatcher] to run [CoroutineWorker] as well.
*
* @param executor An [Executor] for running [Worker]s
* @return This [Builder] instance
@@ -265,6 +292,20 @@
}
/**
+ * Specifies a custom [CoroutineDispatcher] to run [CoroutineWorker.doWork].
+ *
+ * If [setExecutor] wasn't called then [dispatcher] will be used as [Executor]
+ * to run [Worker] as well.
+ *
+ * @param dispatcher A [CoroutineDispatcher] for running [CoroutineWorker]s
+ * @return This [Builder] instance
+ */
+ fun setWorkerCoroutineContext(dispatcher: CoroutineDispatcher): Builder {
+ this.workerContext = dispatcher
+ return this
+ }
+
+ /**
* Specifies a [Executor] which will be used by WorkManager for all its
* internal book-keeping.
*
@@ -512,7 +553,7 @@
}
}
-internal val DEFAULT_CONTENT_URI_TRIGGERS_WORKERS_LIMIT = 8
+internal const val DEFAULT_CONTENT_URI_TRIGGERS_WORKERS_LIMIT = 8
private fun createDefaultExecutor(isTaskExecutor: Boolean): Executor {
val factory = object : ThreadFactory {
@@ -529,3 +570,6 @@
factory
)
}
+
+private fun CoroutineContext?.asExecutor(): Executor? =
+ (this?.get(ContinuationInterceptor) as? CoroutineDispatcher)?.asExecutor()
diff --git a/work/work-runtime/src/main/java/androidx/work/CoroutineWorker.kt b/work/work-runtime/src/main/java/androidx/work/CoroutineWorker.kt
index d56aec9..b546f1c 100644
--- a/work/work-runtime/src/main/java/androidx/work/CoroutineWorker.kt
+++ b/work/work-runtime/src/main/java/androidx/work/CoroutineWorker.kt
@@ -18,33 +18,52 @@
import android.content.Context
import com.google.common.util.concurrent.ListenableFuture
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
+import kotlinx.coroutines.Runnable
/**
- * A [ListenableWorker] implementation that provides interop with Kotlin Coroutines. Override
+ * A [ListenableWorker] implementation that provides interop with Kotlin Coroutines. Override
* the [doWork] function to do your suspending work.
- * <p>
- * By default, CoroutineWorker runs on [Dispatchers.Default]; this can be modified by
- * overriding [coroutineContext].
+ *
+ * By default, CoroutineWorker runs on [Dispatchers.Default] if neither
+ * [Configuration.Builder.setExecutor] or [Configuration.Builder.setWorkerCoroutineContext]
+ * were set.
+ *
* <p>
* A CoroutineWorker is given a maximum of ten minutes to finish its execution and return a
- * [ListenableWorker.Result]. After this time has expired, the worker will be signalled to stop.
+ * [ListenableWorker.Result]. After this time has expired, the worker will be signalled to stop.
*/
public abstract class CoroutineWorker(
appContext: Context,
- params: WorkerParameters
+ private val params: WorkerParameters
) : ListenableWorker(appContext, params) {
/**
- * The coroutine context on which [doWork] will run. By default, this is [Dispatchers.Default].
+ * The coroutine context on which [doWork] will run.
+ *
+ * If this property is overridden then it takes precedent over [Configuration.executor] or
+ * [Configuration.workerCoroutineContext].
+ *
+ * By default, this is a dispatcher delegating to [Dispatchers.Default]
*/
@Deprecated(message = "use withContext(...) inside doWork() instead.")
- public open val coroutineContext: CoroutineDispatcher = Dispatchers.Default
+ public open val coroutineContext: CoroutineDispatcher = DeprecatedDispatcher
@Suppress("DEPRECATION")
public final override fun startWork(): ListenableFuture<Result> {
+ // if a developer didn't override coroutineContext property, then
+ // we use Dispatchers.Default directly.
+ // We can't fully implement delegating CoroutineDispatcher, because CoroutineDispatcher
+ // has experimental and internal apis.
+ val coroutineContext = if (coroutineContext != DeprecatedDispatcher) {
+ coroutineContext
+ } else {
+ params.workerContext
+ }
+
return launchFuture(coroutineContext + Job()) { doWork() }
}
@@ -107,4 +126,15 @@
public final override fun onStopped() {
super.onStopped()
}
+
+ private object DeprecatedDispatcher : CoroutineDispatcher() {
+ val dispatcher = Dispatchers.Default
+ override fun dispatch(context: CoroutineContext, block: Runnable) {
+ dispatcher.dispatch(context, block)
+ }
+
+ override fun isDispatchNeeded(context: CoroutineContext): Boolean {
+ return dispatcher.isDispatchNeeded(context)
+ }
+ }
}
diff --git a/work/work-runtime/src/main/java/androidx/work/WorkerParameters.java b/work/work-runtime/src/main/java/androidx/work/WorkerParameters.java
index fa1d5dd..fa8f5a2 100644
--- a/work/work-runtime/src/main/java/androidx/work/WorkerParameters.java
+++ b/work/work-runtime/src/main/java/androidx/work/WorkerParameters.java
@@ -26,6 +26,8 @@
import androidx.annotation.RestrictTo;
import androidx.work.impl.utils.taskexecutor.TaskExecutor;
+import kotlin.coroutines.CoroutineContext;
+
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -46,6 +48,7 @@
private @NonNull RuntimeExtras mRuntimeExtras;
private int mRunAttemptCount;
private @NonNull Executor mBackgroundExecutor;
+ private @NonNull CoroutineContext mWorkerContext;
private @NonNull TaskExecutor mWorkTaskExecutor;
private @NonNull WorkerFactory mWorkerFactory;
private @NonNull ProgressUpdater mProgressUpdater;
@@ -63,6 +66,7 @@
@IntRange(from = 0) int runAttemptCount,
@IntRange(from = 0) int generation,
@NonNull Executor backgroundExecutor,
+ @NonNull CoroutineContext workerContext,
@NonNull TaskExecutor workTaskExecutor,
@NonNull WorkerFactory workerFactory,
@NonNull ProgressUpdater progressUpdater,
@@ -74,6 +78,7 @@
mRunAttemptCount = runAttemptCount;
mGeneration = generation;
mBackgroundExecutor = backgroundExecutor;
+ mWorkerContext = workerContext;
mWorkTaskExecutor = workTaskExecutor;
mWorkerFactory = workerFactory;
mProgressUpdater = progressUpdater;
@@ -184,6 +189,13 @@
/**
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public @NonNull CoroutineContext getWorkerContext() {
+ return mWorkerContext;
+ }
+
+ /**
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public @NonNull TaskExecutor getTaskExecutor() {
return mWorkTaskExecutor;
}
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt b/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
index fd7b5f6..9e1e1b47 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
+++ b/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
@@ -173,6 +173,7 @@
workSpec.runAttemptCount,
workSpec.generation,
configuration.executor,
+ configuration.workerCoroutineContext,
workTaskExecutor,
configuration.workerFactory,
WorkProgressUpdater(workDatabase, workTaskExecutor),
diff --git a/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt b/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt
index 99ae5f7..cd6c543 100644
--- a/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt
+++ b/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt
@@ -25,6 +25,7 @@
import io.reactivex.Single
import java.util.UUID
import java.util.concurrent.Executor
+import kotlin.coroutines.EmptyCoroutineContext
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -94,6 +95,7 @@
1,
0,
executor,
+ EmptyCoroutineContext,
RxWorkerTest.InstantWorkTaskExecutor(),
DefaultWorkerFactory,
progressUpdater,
diff --git a/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt b/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
index 25e93b7..ada365e 100644
--- a/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
+++ b/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
@@ -26,6 +26,7 @@
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
+import kotlin.coroutines.EmptyCoroutineContext
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert
@@ -127,6 +128,7 @@
1,
0,
executor,
+ EmptyCoroutineContext,
InstantWorkTaskExecutor(),
DefaultWorkerFactory,
progressUpdater,
diff --git a/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt b/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt
index fec7eec..e6a60c4 100644
--- a/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt
+++ b/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt
@@ -22,6 +22,7 @@
import androidx.work.impl.utils.futures.SettableFuture
import java.util.UUID
import java.util.concurrent.Executor
+import kotlin.coroutines.EmptyCoroutineContext
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
@@ -64,6 +65,7 @@
1,
0,
executor,
+ EmptyCoroutineContext,
RxWorkerTest.InstantWorkTaskExecutor(),
DefaultWorkerFactory,
progressUpdater,
diff --git a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt
index 51c70f6..35a6b31 100644
--- a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt
+++ b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt
@@ -31,6 +31,7 @@
import io.reactivex.rxjava3.core.Single
import java.util.UUID
import java.util.concurrent.Executor
+import kotlin.coroutines.EmptyCoroutineContext
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -100,6 +101,7 @@
1,
0,
executor,
+ EmptyCoroutineContext,
RxWorkerTest.InstantWorkTaskExecutor(),
DefaultWorkerFactory,
progressUpdater,
diff --git a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt
index 9edd2de..4d497f3 100644
--- a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt
+++ b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt
@@ -32,6 +32,7 @@
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
+import kotlin.coroutines.EmptyCoroutineContext
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert
@@ -133,6 +134,7 @@
1,
0,
executor,
+ EmptyCoroutineContext,
InstantWorkTaskExecutor(),
DefaultWorkerFactory,
progressUpdater,
diff --git a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt
index 5bc2ab1..b528b562 100644
--- a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt
+++ b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt
@@ -27,6 +27,7 @@
import androidx.work.impl.utils.futures.SettableFuture
import java.util.UUID
import java.util.concurrent.Executor
+import kotlin.coroutines.EmptyCoroutineContext
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
@@ -69,6 +70,7 @@
1,
0,
executor,
+ EmptyCoroutineContext,
RxWorkerTest.InstantWorkTaskExecutor(),
DefaultWorkerFactory,
progressUpdater,
diff --git a/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java b/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java
index 8a65620..c06abc9 100644
--- a/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java
+++ b/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java
@@ -42,6 +42,8 @@
import java.util.UUID;
import java.util.concurrent.Executor;
+import kotlinx.coroutines.Dispatchers;
+
/**
* Builds instances of {@link androidx.work.ListenableWorker} which can be used for testing.
*
@@ -321,6 +323,7 @@
mGeneration,
// This is unused for ListenableWorker
getExecutor(),
+ Dispatchers.getDefault(),
getTaskExecutor(),
mWorkerFactory,
getProgressUpdater(),