Merge "Introduce slots reuse logic in SubcomposeLayout" into androidx-main
diff --git a/activity/integration-tests/testapp/lint-baseline.xml b/activity/integration-tests/testapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/activity/integration-tests/testapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/ads/ads-identifier-benchmark/lint-baseline.xml b/ads/ads-identifier-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/ads/ads-identifier-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/ads/ads-identifier-provider/lint-baseline.xml b/ads/ads-identifier-provider/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/ads/ads-identifier-provider/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/ads/ads-identifier-testing/lint-baseline.xml b/ads/ads-identifier-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/ads/ads-identifier-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/ads/ads-identifier/lint-baseline.xml b/ads/ads-identifier/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/ads/ads-identifier/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/appcompat/appcompat-benchmark/lint-baseline.xml b/appcompat/appcompat-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/appcompat/appcompat-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/appcompat/appcompat-lint/lint-baseline.xml b/appcompat/appcompat-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/appcompat/appcompat-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/appcompat/integration-tests/receive-content-testapp/lint-baseline.xml b/appcompat/integration-tests/receive-content-testapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/appcompat/integration-tests/receive-content-testapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/appsearch/appsearch/lint-baseline.xml b/appsearch/appsearch/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/appsearch/appsearch/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/cts/GenericDocumentCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/cts/GenericDocumentCtsTest.java
index 164adad..4fa033a 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/cts/GenericDocumentCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/cts/GenericDocumentCtsTest.java
@@ -22,6 +22,7 @@
import androidx.appsearch.app.GenericDocument;
+import org.junit.Ignore;
import org.junit.Test;
public class GenericDocumentCtsTest {
@@ -174,6 +175,7 @@
.containsExactly(sDocumentProperties1, sDocumentProperties2);
}
+ @Ignore
@Test
public void testDocument_toString() {
GenericDocument document = new GenericDocument.Builder<>("uri1", "schemaType1")
diff --git a/appsearch/local-storage/lint-baseline.xml b/appsearch/local-storage/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/appsearch/local-storage/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/asynclayoutinflater/asynclayoutinflater/lint-baseline.xml b/asynclayoutinflater/asynclayoutinflater/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/asynclayoutinflater/asynclayoutinflater/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/benchmark/gradle-plugin/lint-baseline.xml b/benchmark/gradle-plugin/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/benchmark/gradle-plugin/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/benchmark/integration-tests/crystalball-experiment/lint-baseline.xml b/benchmark/integration-tests/crystalball-experiment/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/benchmark/integration-tests/crystalball-experiment/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/benchmark/integration-tests/dry-run-benchmark/lint-baseline.xml b/benchmark/integration-tests/dry-run-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/benchmark/integration-tests/dry-run-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/benchmark/integration-tests/startup-benchmark/lint-baseline.xml b/benchmark/integration-tests/startup-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/benchmark/integration-tests/startup-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/biometric/biometric-ktx/lint-baseline.xml b/biometric/biometric-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/biometric/biometric-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/biometric/biometric/lint-baseline.xml b/biometric/biometric/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/biometric/biometric/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/biometric/integration-tests/testapp/lint-baseline.xml b/biometric/integration-tests/testapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/biometric/integration-tests/testapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/buildSrc-tests/lint-baseline.xml b/buildSrc-tests/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/buildSrc-tests/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index 9c8874d..b238e0c 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -52,7 +52,7 @@
val CORE_ANIMATION = Version("1.0.0-alpha03")
val CORE_ANIMATION_TESTING = Version("1.0.0-alpha03")
val CORE_APPDIGEST = Version("1.0.0-alpha01")
- val CORE_GOOGLE_SHORTCUTS = Version("1.0.0-alpha04")
+ val CORE_GOOGLE_SHORTCUTS = Version("1.0.0-beta01")
val CORE_ROLE = Version("1.1.0-alpha02")
val CURSORADAPTER = Version("1.1.0-alpha01")
val CUSTOMVIEW = Version("1.2.0-alpha01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
index bf9cff9..08e2e98 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
@@ -195,22 +195,41 @@
// be able to burn down existing violations. That's hard to enforce, though, so we'll
// generally allow teams to update their baseline files with a publicly-known flag.
if (updateLintBaseline) {
- // Continue generating baselines regardless of errors
+ // Continue generating baselines regardless of errors.
isAbortOnError = false
- // Avoid printing every single lint error to the terminal
+ // Avoid printing every single lint error to the terminal.
textReport = false
- val lintDebugTask = tasks.named("lintDebug")
- lintDebugTask.configure {
- it.doFirst {
- lintBaseline.delete()
+
+ listOf(
+ tasks.named("lintDebug"),
+ tasks.named("lint"),
+ ).forEach { task ->
+ task.configure {
+ // Delete any existing baseline so that we clear old obsolete entries.
+ it.doFirst {
+ lintBaseline.delete()
+ }
+
+ // Delete empty generated baselines because they are annoying.
+ it.doLast {
+ if (lintBaseline.exists()) {
+ val hasAnyIssues = lintBaseline.reader().useLines { lines ->
+ lines.any { line ->
+ line.endsWith("<issue")
+ }
+ }
+ if (!hasAnyIssues) {
+ // Using println is consistent with lint's own output.
+ println(
+ "Removed empty baseline file ${lintBaseline.absolutePath}"
+ )
+ lintBaseline.delete()
+ }
+ }
+ }
}
}
- val lintTask = tasks.named("lint")
- lintTask.configure {
- it.doFirst {
- lintBaseline.delete()
- }
- }
+
// Continue running after errors or after creating a new, blank baseline file.
System.setProperty(LINT_BASELINE_CONTINUE, "true")
}
diff --git a/camera/camera-camera2-pipe-integration/lint-baseline.xml b/camera/camera-camera2-pipe-integration/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/camera/camera-camera2-pipe-integration/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/camera/camera-camera2-pipe-testing/lint-baseline.xml b/camera/camera-camera2-pipe-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/camera/camera-camera2-pipe-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/camera/camera-lifecycle/lint-baseline.xml b/camera/camera-lifecycle/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/camera/camera-lifecycle/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/car/app/app-activity/lint-baseline.xml b/car/app/app-activity/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/car/app/app-activity/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/car/app/app-samples/helloworld/automotive/lint-baseline.xml b/car/app/app-samples/helloworld/automotive/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/car/app/app-samples/helloworld/automotive/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/car/app/app-samples/helloworld/mobile/lint-baseline.xml b/car/app/app-samples/helloworld/mobile/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/car/app/app-samples/helloworld/mobile/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/car/app/app-samples/places/common/lint-baseline.xml b/car/app/app-samples/places/common/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/car/app/app-samples/places/common/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/car/app/app-testing/lint-baseline.xml b/car/app/app-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/car/app/app-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/cardview/cardview/lint-baseline.xml b/cardview/cardview/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/cardview/cardview/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/collection/collection-benchmark/lint-baseline.xml b/collection/collection-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/collection/collection-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/collection/collection-ktx/lint-baseline.xml b/collection/collection-ktx/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/collection/collection-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/collection/integration-tests/testapp/lint-baseline.xml b/collection/integration-tests/testapp/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/collection/integration-tests/testapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
index a7e6062..5f0aad8 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractIrTransformTest.kt
@@ -206,6 +206,11 @@
"${it.groupValues[1]}<>"
}
}
+ .replace(
+ Regex("(sourceInformationMarkerStart\\(%composer, )([-\\d]+)")
+ ) {
+ "${it.groupValues[1]}<>"
+ }
// replace source information with source it references
.replace(
Regex(
@@ -214,10 +219,15 @@
)
) {
"${it.groupValues[1]}\"${
- generateSourceInfo(it.groupValues[3], source)
+ generateSourceInfo(it.groupValues[4], source)
}\")"
}
.replace(
+ Regex("(sourceInformation(MarkerStart)?\\(.*)\"(.*)\"\\)")
+ ) {
+ "${it.groupValues[1]}\"${generateSourceInfo(it.groupValues[3], source)}\")"
+ }
+ .replace(
Regex(
"(composableLambda[N]?\\" +
"([^\"\\n]*)\"(.*)\"\\)"
@@ -235,16 +245,15 @@
) {
"${it.groupValues[1]}<>"
}
- // composableLambdaInstance(<>, true, )
+ // composableLambdaInstance(<>, true)
.replace(
Regex(
- "(composableLambdaInstance\\()([-\\d]+, (true|false), (null|\"(.*)\")\\))"
+ "(composableLambdaInstance\\()([-\\d]+, (true|false))"
)
) {
val callStart = it.groupValues[1]
val tracked = it.groupValues[3]
- val sourceInfo = it.groupValues[5]
- "$callStart<>, $tracked, \"${generateSourceInfo(sourceInfo, source)}\")"
+ "$callStart<>, $tracked"
}
// composableLambda(%composer, <>, true)
.replace(
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ClassStabilityTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ClassStabilityTransformTests.kt
index 0c6ce92..9cddb39 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ClassStabilityTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ClassStabilityTransformTests.kt
@@ -543,7 +543,8 @@
"""
@Composable
fun A(y: Any?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<A()>,<A(Empt...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(X(li...>,<A(X(li...>,<A(NonB...>,<A(NonB...>,<A(Stab...>,<A(Unst...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<A()>,<A(Empt...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Sing...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(Doub...>,<A(X(li...>,<A(X(li...>,<A(NonB...>,<A(NonB...>,<A(Stab...>,<A(Unst...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0010
@@ -674,7 +675,8 @@
}
@Composable
fun A(y: Any, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<A(X(li...>,<A(Stab...>,<A(Unst...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<A(X(li...>,<A(Stab...>,<A(Unst...>:Test.kt")
used(y)
A(X(listOf(StableClass())), %composer, 0b1000)
A(StableDelegateProp(), %composer, 0)
@@ -708,7 +710,8 @@
"""
@Composable
fun A(y: Any, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<A(Wrap...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<A(Wrap...>:Test.kt")
used(y)
A(Wrapper(Foo()), %composer, Wrapper.%stable)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
@@ -746,7 +749,8 @@
"""
@Composable
fun <V> B(value: V, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B)<A(Wrap...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B)<A(Wrap...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(value)) 0b0100 else 0b0010
@@ -762,7 +766,8 @@
}
@Composable
fun <T> X(items: List<T>, itemContent: Function3<T, Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(X)P(1)*<itemCo...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(X)P(1)*<itemCo...>:Test.kt")
val %dirty = %changed
val tmp0_iterator = items.iterator()
while (tmp0_iterator.hasNext()) {
@@ -775,14 +780,16 @@
}
@Composable
fun C(items: List<String>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(C)<X(item...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(C)<X(item...>:Test.kt")
X(items, ComposableSingletons%TestKt.lambda-1, %composer, 0b1000)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
C(items, %composer, %changed or 0b0001)
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function3<String, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<A(item...>,<A(Wrap...>:Test.kt") { item: String, %composer: Composer?, %changed: Int ->
+ val lambda-1: Function3<String, Composer, Int, Unit> = composableLambdaInstance(<>, false) { item: String, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A(item...>,<A(Wrap...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(item)) 0b0100 else 0b0010
@@ -837,7 +844,8 @@
}
@Composable
fun A(y: Int, x: Any, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)P(1)<B(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)P(1)<B(x)>:Test.kt")
used(y)
B(x, %composer, 0b1000)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
@@ -846,7 +854,8 @@
}
@Composable
fun B(x: Any, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B):Test.kt")
used(x)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
B(x, %composer, %changed or 0b0001)
@@ -876,7 +885,8 @@
}
@Composable
fun A(y: Int, x: Foo, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)P(1)<B(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)P(1)<B(x)>:Test.kt")
used(y)
B(x, %composer, 0b1000)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
@@ -885,7 +895,8 @@
}
@Composable
fun B(x: Any, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B):Test.kt")
used(x)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
B(x, %composer, %changed or 0b0001)
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
index 26c88f32..ae972e1 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
@@ -67,7 +67,8 @@
val bar: Int
@Composable @JvmName(name = "getBar")
get() {
- %composer.startReplaceableGroup(<>, "C:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C:Test.kt#2487m")
val tmp0 = 123
%composer.endReplaceableGroup()
return tmp0
@@ -75,7 +76,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<bar>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<bar>:Test.kt#2487m")
bar
%composer.endReplaceableGroup()
}
@@ -110,7 +112,8 @@
@NonRestartableComposable
@Composable
override fun bar(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(bar):Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(bar):Test.kt#2487m")
%composer.endReplaceableGroup()
}
static val %stable: Int = 0
@@ -143,18 +146,21 @@
@NonRestartableComposable
@Composable
fun Wat(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Wat):Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Wat):Test.kt#2487m")
%composer.endReplaceableGroup()
}
@NonRestartableComposable
@Composable
fun Foo(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Foo)<Wat()>,<goo()>,<baz()>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Foo)<Wat()>,<goo()>,<baz()>:Test.kt#2487m")
Wat(%composer, 0)
@NonRestartableComposable
@Composable
fun goo(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(goo)<Wat()>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(goo)<Wat()>:Test.kt#2487m")
Wat(%composer, 0)
%composer.endReplaceableGroup()
}
@@ -162,7 +168,8 @@
@NonRestartableComposable
@Composable
fun baz(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(baz)<Wat()>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(baz)<Wat()>:Test.kt#2487m")
Wat(%composer, 0)
%composer.endReplaceableGroup()
}
@@ -245,7 +252,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<Exampl...>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<Exampl...>:Test.kt#2487m")
Example(%composer, 0)
%composer.endReplaceableGroup()
}
@@ -267,16 +275,19 @@
"""
@Composable
fun Example(content: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<conten...>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<conten...>:Test.kt#2487m")
content(%composer, 0b1110 and %changed)
%composer.endReplaceableGroup()
}
@NonRestartableComposable
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Test)<Exampl...>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Test)<Exampl...>:Test.kt#2487m")
Example({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>, "C:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C:Test.kt#2487m")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -300,7 +311,8 @@
val myProperty: Function0<Unit>
@Composable @JvmName(name = "getMyProperty")
get() {
- %composer.startReplaceableGroup(<>, "C:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C:Test.kt#2487m")
val tmp0 = {
}
%composer.endReplaceableGroup()
@@ -369,7 +381,8 @@
"""
@Composable
fun Wrapper(block: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Wrapper)<block(...>:Test.kt#2487m")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Wrapper)<block(...>:Test.kt#2487m")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(block)) 0b0100 else 0b0010
@@ -385,7 +398,8 @@
}
@Composable
fun Leaf(text: String, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Leaf):Test.kt#2487m")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Leaf):Test.kt#2487m")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
@@ -401,14 +415,17 @@
}
@Composable
fun Test(value: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt#2487m")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt#2487m")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(value)) 0b0100 else 0b0010
}
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
- %composer.startMovableGroup(<>, value, "<Wrappe...>")
- Wrapper(composableLambda(%composer, <>, true, "C<Leaf("...>:Test.kt#2487m") { %composer: Composer?, %changed: Int ->
+ %composer.startMovableGroup(<>, value)
+ sourceInformation(%composer, "<Wrappe...>")
+ Wrapper(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<Leaf("...>:Test.kt#2487m")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Leaf("Value %value", %composer, 0)
} else {
@@ -486,17 +503,20 @@
"""
@Composable
fun composeVector(composable: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(composeVector)<emit>:Test.kt#2487m")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(composeVector)<emit>:Test.kt#2487m")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(composable)) 0b0100 else 0b0010
}
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
emit({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>, "C<emit>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C<emit>:Test.kt#2487m")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
emit({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>, "C<compos...>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C<compos...>:Test.kt#2487m")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
composable(%composer, 0b1110 and %dirty)
} else {
@@ -518,7 +538,8 @@
}
@Composable
fun emit(composable: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(emit)<compos...>:Test.kt#2487m")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(emit)<compos...>:Test.kt#2487m")
composable(%composer, 0b1110 and %changed)
%composer.endReplaceableGroup()
}
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
index 53823d7..943df22 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
@@ -35,7 +35,8 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
NA()
}
@@ -61,9 +62,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endReplaceableGroup()
} else {
@@ -94,13 +97,16 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endReplaceableGroup()
} else {
- %composer.startReplaceableGroup(<>, "<A(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -128,7 +134,8 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<B()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<B()>:Test.kt")
if (B(%composer, 0)) {
NA()
} else {
@@ -162,13 +169,16 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
- if (%composer.startReplaceableGroup(<>, "<B(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
+ if (%composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<B(a)>")
val tmp0_group = B(a, %composer, 0)
%composer.endReplaceableGroup()
tmp0_group) {
NA()
- } else if (%composer.startReplaceableGroup(<>, "<B(b)>")
+ } else if (%composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<B(b)>")
val tmp1_group = B(b, %composer, 0)
%composer.endReplaceableGroup()
tmp1_group) {
@@ -198,7 +208,8 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val tmp0_subject = x
when {
tmp0_subject == 0 -> {
@@ -235,21 +246,25 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val tmp0_subject = x
when {
tmp0_subject == 0 -> {
- %composer.startReplaceableGroup(<>, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endReplaceableGroup()
}
tmp0_subject == 0b0001 -> {
- %composer.startReplaceableGroup(<>, "<A(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endReplaceableGroup()
}
else -> {
- %composer.startReplaceableGroup(<>, "<A(c)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(c)>")
A(c, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -278,23 +293,27 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val y = val tmp0_subject = x
when {
tmp0_subject == 0 -> {
- %composer.startReplaceableGroup(<>, "<R(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(a)>")
val tmp0_group = R(a, %composer, 0)
%composer.endReplaceableGroup()
tmp0_group
}
tmp0_subject == 0b0001 -> {
- %composer.startReplaceableGroup(<>, "<R(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(b)>")
val tmp1_group = R(b, %composer, 0)
%composer.endReplaceableGroup()
tmp1_group
}
else -> {
- %composer.startReplaceableGroup(<>, "<R(c)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(c)>")
val tmp2_group = R(c, %composer, 0)
%composer.endReplaceableGroup()
tmp2_group
@@ -324,20 +343,24 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
when {
x < 0 -> {
- %composer.startReplaceableGroup(<>, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endReplaceableGroup()
}
x > 30 -> {
- %composer.startReplaceableGroup(<>, "<A(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endReplaceableGroup()
}
else -> {
- %composer.startReplaceableGroup(<>, "<A(c)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(c)>")
A(c, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -366,10 +389,12 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
when {
x < 0 -> {
- %composer.startReplaceableGroup(<>, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -379,7 +404,8 @@
NA()
}
else -> {
- %composer.startReplaceableGroup(<>, "<A(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -409,15 +435,18 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
when {
- %composer.startReplaceableGroup(<>, "<R(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(a)>")
val tmp0_group = x == R(a, %composer, 0)
%composer.endReplaceableGroup()
tmp0_group -> {
NA()
}
- %composer.startReplaceableGroup(<>, "<R(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(b)>")
val tmp1_group = x > R(b, %composer, 0)
%composer.endReplaceableGroup()
tmp1_group -> {
@@ -452,16 +481,20 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "")
when {
- %composer.startReplaceableGroup(<>, "<R(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(a)>")
val tmp0_group = x == R(a, %composer, 0)
%composer.endReplaceableGroup()
tmp0_group -> {
NA()
}
- %composer.startReplaceableGroup(<>, "<R(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R(b)>")
val tmp1_group = x > R(b, %composer, 0)
%composer.endReplaceableGroup()
tmp1_group -> {
@@ -492,7 +525,8 @@
@NonRestartableComposable
@Composable
fun Example(x: Int?, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val tmp0_safe_receiver = x
when {
tmp0_safe_receiver == null -> {
@@ -501,7 +535,8 @@
null
}
else -> {
- %composer.startReplaceableGroup(<>, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>")
tmp0_safe_receiver.A(%composer, 0b1110 and %changed)
%composer.endReplaceableGroup()
}
@@ -525,11 +560,13 @@
@NonRestartableComposable
@Composable
fun Example(x: Int?, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val y = val tmp0_elvis_lhs = x
when {
tmp0_elvis_lhs == null -> {
- %composer.startReplaceableGroup(<>, "<R()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R()>")
val tmp0_group = R(%composer, 0)
%composer.endReplaceableGroup()
tmp0_group
@@ -562,7 +599,8 @@
@NonRestartableComposable
@Composable
fun Example(items: List<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<P(i)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(i)>:Test.kt")
val tmp0_iterator = items.iterator()
while (tmp0_iterator.hasNext()) {
val i = tmp0_iterator.next()
@@ -590,8 +628,10 @@
@NonRestartableComposable
@Composable
fun Example(items: List<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<P(i)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<P(i)>")
val tmp0_iterator = items.iterator()
while (tmp0_iterator.hasNext()) {
val i = tmp0_iterator.next()
@@ -620,7 +660,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<L()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<L()>:Test.kt")
val tmp0_iterator = L(%composer, 0).iterator()
while (tmp0_iterator.hasNext()) {
val i = tmp0_iterator.next()
@@ -650,7 +691,8 @@
@NonRestartableComposable
@Composable
fun Example(items: MutableList<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<P(item...>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(item...>:Test.kt")
while (items.isNotEmpty()) {
val item = items.removeAt(items.size - 1)
P(item, %composer, 0)
@@ -679,8 +721,10 @@
@NonRestartableComposable
@Composable
fun Example(items: MutableList<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<P(item...>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<P(item...>")
while (items.isNotEmpty()) {
val item = items.removeAt(items.size - 1)
P(item, %composer, 0)
@@ -709,7 +753,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<B()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<B()>:Test.kt")
while (B(%composer, 0)) {
print("hello world")
}
@@ -735,8 +780,10 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<B()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<B()>")
while (B(%composer, 0)) {
print("hello world")
}
@@ -764,7 +811,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<B()>,<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<B()>,<A()>:Test.kt")
while (B(%composer, 0)) {
A(%composer, 0)
}
@@ -791,8 +839,10 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A(b)>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<B()>,<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A(b)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<B()>,<A(a)>")
while (B(%composer, 0)) {
A(a, %composer, 0)
}
@@ -820,9 +870,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endReplaceableGroup()
%composer.endReplaceableGroup()
@@ -853,7 +905,8 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (x > 0) {
%composer.endReplaceableGroup()
return
@@ -880,9 +933,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
val tmp1_return = 1
%composer.endReplaceableGroup()
@@ -915,7 +970,8 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
if (x > 0) {
val tmp1_return = 1
%composer.endReplaceableGroup()
@@ -944,7 +1000,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>,<R()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>,<R()>:Test.kt")
A(%composer, 0)
val tmp0 = R(%composer, 0)
%composer.endReplaceableGroup()
@@ -968,9 +1025,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Example)<R()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<R()>:Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<R()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<R()>")
val tmp1_return = R(%composer, 0)
%composer.endReplaceableGroup()
%composer.endReplaceableGroup()
@@ -1011,7 +1070,8 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<P(i)>,<P(l)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(i)>,<P(l)>:Test.kt")
while (items.hasNext()) {
val i = items.next()
val j = i
@@ -1019,13 +1079,15 @@
val l = i
P(i, %composer, 0)
if (i == 0) {
- %composer.startReplaceableGroup(<>, "<P(j)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(j)>")
P(j, %composer, 0)
%composer.endReplaceableGroup()
%composer.endReplaceableGroup()
return
} else {
- %composer.startReplaceableGroup(<>, "<P(k)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(k)>")
P(k, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -1060,7 +1122,8 @@
"""
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)*<P(i)>,<P(l)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(i)>,<P(l)>:Test.kt")
while (items.hasNext()) {
val i = items.next()
val j = i
@@ -1068,7 +1131,8 @@
val l = i
P(i, %composer, 0)
if (i == 0) {
- %composer.startReplaceableGroup(<>, "<P(j)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(j)>")
P(j, %composer, 0)
%composer.endReplaceableGroup()
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
@@ -1076,7 +1140,8 @@
}
return
} else {
- %composer.startReplaceableGroup(<>, "<P(k)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(k)>")
P(k, %composer, 0)
%composer.endReplaceableGroup()
}
@@ -1107,7 +1172,8 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<P(i)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(i)>:Test.kt")
while (items.hasNext()) {
val i = items.next()
if (i == 0) {
@@ -1138,7 +1204,8 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<P(i)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(i)>:Test.kt")
while (items.hasNext()) {
val i = items.next()
P(i, %composer, 0)
@@ -1172,7 +1239,8 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<P(i)>,<P(j)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<P(i)>,<P(j)>:Test.kt")
while (items.hasNext()) {
val i = items.next()
val j = i
@@ -1208,8 +1276,10 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<P(i)>,<P(i)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<P(i)>,<P(i)>")
while (items.hasNext()) {
val i = items.next()
P(i, %composer, 0)
@@ -1243,9 +1313,11 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>, "<P(i)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(i)>")
val i = items.next()
if (i == 0) {
%composer.endReplaceableGroup()
@@ -1278,9 +1350,11 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>, "<P(i)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(i)>")
val i = items.next()
P(i, %composer, 0)
if (i == 0) {
@@ -1314,9 +1388,11 @@
@NonRestartableComposable
@Composable
fun Example(items: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
while (items.hasNext()) {
- %composer.startReplaceableGroup(<>, "<P(i)>,<P(i)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<P(i)>,<P(i)>")
val i = items.next()
P(i, %composer, 0)
if (i == 0) {
@@ -1349,7 +1425,8 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
while (a.hasNext()) {
val x = a.next()
if (x > 100) {
@@ -1385,10 +1462,12 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
a@while (a.hasNext()) {
val x = a.next()
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
val y = b.next()
if (y == x) {
@@ -1436,13 +1515,15 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<A()>:Test.kt")
a@while (a.hasNext()) {
val x = a.next()
if (x == 0) {
break
}
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
val y = b.next()
if (y == 0) {
@@ -1485,10 +1566,13 @@
@NonRestartableComposable
@Composable
fun Example(a: Iterator<Int>, b: Iterator<Int>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
a@while (a.hasNext()) {
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
b@while (b.hasNext()) {
A(%composer, 0)
}
@@ -1519,10 +1603,13 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A()>")
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
while (x > 0) {
A(%composer, 0)
}
@@ -1555,9 +1642,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A()>,*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>,*<A()>")
A(%composer, 0)
while (x > 0) {
A(%composer, 0)
@@ -1588,9 +1677,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
while (x > 0) {
A(%composer, 0)
}
@@ -1620,9 +1711,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
while (x > 0) {
- %composer.startMovableGroup(<>, x, "<A()>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endMovableGroup()
}
@@ -1650,12 +1743,15 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
while (x > 0) {
- %composer.startMovableGroup(<>, x, "<A(a)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endMovableGroup()
- %composer.startMovableGroup(<>, x + 1, "<A(b)>")
+ %composer.startMovableGroup(<>, x + 1)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endMovableGroup()
}
@@ -1681,9 +1777,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<A(b)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<A(b)>:Test.kt")
while (x > 0) {
- %composer.startMovableGroup(<>, x, "<A(a)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endMovableGroup()
A(b, %composer, 0)
@@ -1710,10 +1808,12 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<A(a)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<A(a)>:Test.kt")
while (x > 0) {
A(a, %composer, 0)
- %composer.startMovableGroup(<>, x, "<A(b)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endMovableGroup()
}
@@ -1740,10 +1840,12 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<A(a)>,<A(c)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<A(a)>,<A(c)>:Test.kt")
while (x > 0) {
A(a, %composer, 0)
- %composer.startMovableGroup(<>, x, "<A(b)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endMovableGroup()
A(c, %composer, 0)
@@ -1767,8 +1869,10 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
- %composer.startMovableGroup(<>, x, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endMovableGroup()
%composer.endReplaceableGroup()
@@ -1791,8 +1895,10 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A(b)>:Test.kt")
- %composer.startMovableGroup(<>, x, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A(b)>:Test.kt")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endMovableGroup()
A(b, %composer, 0)
@@ -1816,9 +1922,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<A(a)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<A(a)>:Test.kt")
A(a, %composer, 0)
- %composer.startMovableGroup(<>, x, "<A(b)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endMovableGroup()
%composer.endReplaceableGroup()
@@ -1842,10 +1950,13 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "")
- %composer.startMovableGroup(<>, x, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endMovableGroup()
%composer.endReplaceableGroup()
@@ -1875,10 +1986,13 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A(b)>")
- %composer.startMovableGroup(<>, x, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(b)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endMovableGroup()
A(b, %composer, 0)
@@ -1909,11 +2023,14 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
- %composer.startMovableGroup(<>, x, "<A(b)>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<A(b)>")
A(b, %composer, 0)
%composer.endMovableGroup()
%composer.endReplaceableGroup()
@@ -1940,8 +2057,10 @@
@NonRestartableComposable
@Composable
fun Example(a: Int, b: Int, c: Int, d: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
- %composer.startMovableGroup(<>, %composer.joinKey(%composer.joinKey(%composer.joinKey(a, b), c), d), "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
+ %composer.startMovableGroup(<>, %composer.joinKey(%composer.joinKey(%composer.joinKey(a, b), c), d))
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endMovableGroup()
%composer.endReplaceableGroup()
@@ -1965,9 +2084,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)*<R()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)*<R()>:Test.kt")
while (x > 0) {
- %composer.startMovableGroup(<>, R(%composer, 0), "<A()>")
+ %composer.startMovableGroup(<>, R(%composer, 0))
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endMovableGroup()
}
@@ -1989,9 +2110,11 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<P(y)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<P(y)>:Test.kt")
val y =
- %composer.startMovableGroup(<>, x, "<R()>")
+ %composer.startMovableGroup(<>, x)
+ sourceInformation(%composer, "<R()>")
val tmp0 = R(%composer, 0)
%composer.endMovableGroup()
tmp0
@@ -2017,14 +2140,18 @@
@NonRestartableComposable
@Composable
fun Example(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Example):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val tmp0 = if (x > 0) {
- %composer.startReplaceableGroup(<>, "")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "")
val tmp4_group =
- val tmp3_group = if (%composer.startReplaceableGroup(<>, "<B()>")
+ val tmp3_group = if (%composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<B()>")
val tmp1_group = B(%composer, 0)
%composer.endReplaceableGroup()
- tmp1_group) 1 else if (%composer.startReplaceableGroup(<>, "<B()>")
+ tmp1_group) 1 else if (%composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<B()>")
val tmp2_group = B(%composer, 0)
%composer.endReplaceableGroup()
tmp2_group) 2 else 3
@@ -2091,8 +2218,10 @@
@NonRestartableComposable
@Composable
fun Simple(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Simple)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Simple)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
}
@@ -2103,8 +2232,10 @@
@NonRestartableComposable
@Composable
fun WithReturn(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(WithReturn)<A()>:Test.kt")
- %composer.startReplaceableGroup(<>, "*<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(WithReturn)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A()>")
run {
A(%composer, 0)
%composer.endReplaceableGroup()
@@ -2118,7 +2249,8 @@
@NonRestartableComposable
@Composable
fun NoCalls(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(NoCalls)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(NoCalls)<A()>:Test.kt")
run {
println("hello world")
}
@@ -2128,7 +2260,8 @@
@NonRestartableComposable
@Composable
fun NoCallsAfter(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(NoCallsAfter)*<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(NoCallsAfter)*<A()>:Test.kt")
run {
A(%composer, 0)
}
@@ -2154,7 +2287,8 @@
"""
@Composable
fun Example(x: Int?, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<A(c)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<A(c)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -2168,10 +2302,12 @@
null
}
else -> {
- %composer.startReplaceableGroup(<>, "*<A(b)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<A(b)>")
tmp0_safe_receiver.let { it: Int ->
if (it > 0) {
- %composer.startReplaceableGroup(<>, "<A(a)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(a)>")
A(a, %composer, 0)
%composer.endReplaceableGroup()
} else {
@@ -2211,7 +2347,8 @@
"""
@Composable
fun Example(x: Int?, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<A()>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<A()>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -2249,7 +2386,8 @@
"""
@Composable
fun <T> provided(value: T, %composer: Composer?, %changed: Int): State<T> {
- %composer.startReplaceableGroup(<>, "C(provided)*<rememb...>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(provided)*<rememb...>:Test.kt")
val tmp0 = remember({
val tmp0_return = mutableStateOf(
value = value
@@ -2282,7 +2420,8 @@
"""
@Composable
fun Test(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Test)*<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Test)*<A()>:Test.kt")
val tmp0 =
val tmp1_group = x.let { it: Int ->
A(%composer, 0)
@@ -2309,7 +2448,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<W>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<W>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
W(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -2320,7 +2460,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<A()>:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A()>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
A(%composer, 0)
} else {
@@ -2344,10 +2485,12 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<IW>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<IW>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
IW({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>, "C<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C<A()>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
A(%composer, 0)
} else {
@@ -2383,7 +2526,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<Wrap>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<Wrap>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
Wrap(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -2394,9 +2538,11 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<effect>:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<effect>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
- %composer.startReplaceableGroup(<>, "*<effect>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<effect>")
repeat(number) { it: Int ->
effects[it] = effect({
0
@@ -2437,7 +2583,8 @@
"""
@Composable
fun Test(value: InlineClass, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)P(0:InlineClass)<A()>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)P(0:InlineClass)<A()>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(value.value)) 0b0100 else 0b0010
@@ -2606,7 +2753,8 @@
"""
@Composable
fun Test01(p0: Int, p1: Int, p2: Int, p3: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test01):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test01):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
@@ -2634,7 +2782,8 @@
}
@Composable
fun Test02(p0: Int, p1: Int, p3: Int, p2: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test02)P(!2,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test02)P(!2,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
@@ -2662,7 +2811,8 @@
}
@Composable
fun Test03(p0: Int, p2: Int, p1: Int, p3: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test03)P(!1,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test03)P(!1,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
@@ -2690,7 +2840,8 @@
}
@Composable
fun Test04(p0: Int, p2: Int, p3: Int, p1: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test04)P(!1,2,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test04)P(!1,2,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
@@ -2718,7 +2869,8 @@
}
@Composable
fun Test05(p0: Int, p3: Int, p1: Int, p2: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test05)P(!1,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test05)P(!1,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
@@ -2746,7 +2898,8 @@
}
@Composable
fun Test06(p0: Int, p3: Int, p2: Int, p1: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test06)P(!1,3,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test06)P(!1,3,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p0)) 0b0100 else 0b0010
@@ -2774,7 +2927,8 @@
}
@Composable
fun Test07(p1: Int, p0: Int, p2: Int, p3: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test07)P(1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test07)P(1):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
@@ -2802,7 +2956,8 @@
}
@Composable
fun Test08(p1: Int, p0: Int, p3: Int, p2: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test08)P(1!1,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test08)P(1!1,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
@@ -2830,7 +2985,8 @@
}
@Composable
fun Test09(p1: Int, p2: Int, p0: Int, p3: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test09)P(1,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test09)P(1,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
@@ -2858,7 +3014,8 @@
}
@Composable
fun Test00(p1: Int, p2: Int, p3: Int, p0: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test00)P(1,2,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test00)P(1,2,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
@@ -2886,7 +3043,8 @@
}
@Composable
fun Test11(p1: Int, p3: Int, p0: Int, p2: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test11)P(1,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test11)P(1,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
@@ -2914,7 +3072,8 @@
}
@Composable
fun Test12(p1: Int, p3: Int, p2: Int, p0: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test12)P(1,3,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test12)P(1,3,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p1)) 0b0100 else 0b0010
@@ -2942,7 +3101,8 @@
}
@Composable
fun Test13(p2: Int, p0: Int, p1: Int, p3: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test13)P(2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test13)P(2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
@@ -2970,7 +3130,8 @@
}
@Composable
fun Test14(p2: Int, p0: Int, p3: Int, p1: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test14)P(2!1,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test14)P(2!1,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
@@ -2998,7 +3159,8 @@
}
@Composable
fun Test15(p2: Int, p1: Int, p0: Int, p3: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test15)P(2,1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test15)P(2,1):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
@@ -3026,7 +3188,8 @@
}
@Composable
fun Test16(p2: Int, p1: Int, p3: Int, p0: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test16)P(2,1,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test16)P(2,1,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
@@ -3054,7 +3217,8 @@
}
@Composable
fun Test17(p2: Int, p3: Int, p0: Int, p1: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test17)P(2,3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test17)P(2,3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
@@ -3082,7 +3246,8 @@
}
@Composable
fun Test18(p2: Int, p3: Int, p1: Int, p0: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test18)P(2,3,1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test18)P(2,3,1):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p2)) 0b0100 else 0b0010
@@ -3110,7 +3275,8 @@
}
@Composable
fun Test19(p3: Int, p0: Int, p1: Int, p2: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test19)P(3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test19)P(3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
@@ -3138,7 +3304,8 @@
}
@Composable
fun Test20(p3: Int, p0: Int, p2: Int, p1: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test20)P(3!1,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test20)P(3!1,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
@@ -3166,7 +3333,8 @@
}
@Composable
fun Test21(p3: Int, p1: Int, p0: Int, p2: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test21)P(3,1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test21)P(3,1):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
@@ -3194,7 +3362,8 @@
}
@Composable
fun Test22(p3: Int, p1: Int, p2: Int, p0: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test22)P(3,1,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test22)P(3,1,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
@@ -3222,7 +3391,8 @@
}
@Composable
fun Test23(p3: Int, p2: Int, p0: Int, p1: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test23)P(3,2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test23)P(3,2):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
@@ -3250,7 +3420,8 @@
}
@Composable
fun Test24(p3: Int, p2: Int, p1: Int, p0: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test24)P(3,2,1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test24)P(3,2,1):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(p3)) 0b0100 else 0b0010
@@ -3300,7 +3471,8 @@
expectedTransformed = """
@Composable
fun Test(value: LocalInlineClass, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)P(0:c#runtime.tests.LocalInlineClass):Test.kt#992ot2")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)P(0:c#runtime.tests.LocalInlineClass):Test.kt#992ot2")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(value.value)) 0b0100 else 0b0010
@@ -3340,7 +3512,8 @@
expectedTransformed = """
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<b()>,<c()>,<d()>,<A(b(),>,<B()>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<b()>,<c()>,<d()>,<A(b(),>,<B()>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
A(b(%composer, 0), c(%composer, 0), d(%composer, 0), %composer, 0)
B(%composer, 0)
@@ -3388,7 +3561,8 @@
class SomeClass {
var a: String = "Test"
fun onCreate() {
- setContent(composableLambdaInstance(<>, true, "C<B(a)>,<B(a)>:Test.kt") { %composer: Composer?, %changed: Int ->
+ setContent(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<B(a)>,<B(a)>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
B(a, %composer, 0)
B(a, %composer, 0)
@@ -3402,7 +3576,8 @@
}
fun Test() {
var a = "Test"
- setContent(composableLambdaInstance(<>, true, "C<B(a)>,<B(a)>:Test.kt") { %composer: Composer?, %changed: Int ->
+ setContent(composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<B(a)>,<B(a)>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
B(a, %composer, 0)
B(a, %composer, 0)
@@ -3443,7 +3618,8 @@
expectedTransformed = """
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<W>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<W>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
W(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -3454,13 +3630,16 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<IW>:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<IW>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
IW({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>, "C<T(2)>,<T(4)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C<T(2)>,<T(4)>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
T(2, %composer, 0b0110)
- %composer.startReplaceableGroup(<>, "*<T(3)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "*<T(3)>")
repeat(3) { it: Int ->
T(3, %composer, 0b0110)
}
@@ -3509,27 +3688,138 @@
val current: Int
@Composable @ReadOnlyComposable @JvmName(name = "getCurrent")
get() {
- %composer.startReplaceableGroup(<>, "C:Test.kt")
+ sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
val tmp0 = 0
- %composer.endReplaceableGroup()
+ sourceInformationMarkerEnd(%composer)
return tmp0
}
@Composable
@ReadOnlyComposable
fun calculateSometing(%composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(calculateSometing):Test.kt")
+ sourceInformationMarkerStart(%composer, <>, "C(calculateSometing):Test.kt")
val tmp0 = 0
- %composer.endReplaceableGroup()
+ sourceInformationMarkerEnd(%composer)
return tmp0
}
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<curren...>,<calcul...>,<Layout>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<curren...>,<calcul...>,<Layout>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val c = current
val cl = calculateSometing(%composer, 0)
Layout({ %composer: Composer?, %changed: Int ->
- %composer.startReplaceableGroup(<>, "C<Text("...>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C<Text("...>:Test.kt")
+ if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
+ Text("%c %cl", %composer, 0)
+ } else {
+ %composer.skipToGroupEnd()
+ }
+ %composer.endReplaceableGroup()
+ }, %composer, 0)
+ } else {
+ %composer.skipToGroupEnd()
+ }
+ %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+ Test(%composer, %changed or 0b0001)
+ }
+ }
+ """,
+ """
+ import androidx.compose.runtime.Composable
+
+ @Composable
+ inline fun Layout(content: @Composable () -> Unit) { content() }
+
+ @Composable
+ fun Text(text: String) { }
+ """
+ )
+
+ @Test
+ fun testReadOnlyInlineValSourceLocations() = verifyComposeIrTransform(
+ """
+ import androidx.compose.runtime.Composable
+ import androidx.compose.runtime.ReadOnlyComposable
+
+ class CurrentHolder {
+ inline val current: Int
+ @ReadOnlyComposable
+ @Composable
+ get() = 0
+ }
+
+ class HolderHolder {
+ private val _currentHolder = CurrentHolder()
+ val current: Int
+ @ReadOnlyComposable
+ @Composable
+ get() = _currentHolder.current
+ }
+
+ val holderHolder = HolderHolder()
+
+ @Composable
+ @ReadOnlyComposable
+ fun calculateSometing(): Int {
+ return 0;
+ }
+
+ @Composable
+ fun Test() {
+ val c = holderHolder.current
+ val cl = calculateSometing()
+ Layout {
+ Text("${'$'}c ${'$'}cl")
+ }
+ }
+ """,
+ """
+ @StabilityInferred(parameters = 0)
+ class CurrentHolder {
+ val current: Int
+ @ReadOnlyComposable @Composable @JvmName(name = "getCurrent")
+ get() {
+ sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
+ val tmp0 = 0
+ sourceInformationMarkerEnd(%composer)
+ return tmp0
+ }
+ static val %stable: Int = 0
+ }
+ @StabilityInferred(parameters = 0)
+ class HolderHolder {
+ val _currentHolder: CurrentHolder = CurrentHolder()
+ val current: Int
+ @ReadOnlyComposable @Composable @JvmName(name = "getCurrent")
+ get() {
+ sourceInformationMarkerStart(%composer, <>, "C<curren...>:Test.kt")
+ val tmp0 = _currentHolder.current
+ sourceInformationMarkerEnd(%composer)
+ return tmp0
+ }
+ static val %stable: Int = 0
+ }
+ val holderHolder: HolderHolder = HolderHolder()
+ @Composable
+ @ReadOnlyComposable
+ fun calculateSometing(%composer: Composer?, %changed: Int): Int {
+ sourceInformationMarkerStart(%composer, <>, "C(calculateSometing):Test.kt")
+ val tmp0 = 0
+ sourceInformationMarkerEnd(%composer)
+ return tmp0
+ }
+ @Composable
+ fun Test(%composer: Composer?, %changed: Int) {
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<curren...>,<calcul...>,<Layout>:Test.kt")
+ if (%changed !== 0 || !%composer.skipping) {
+ val c = holderHolder.current
+ val cl = calculateSometing(%composer, 0)
+ Layout({ %composer: Composer?, %changed: Int ->
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C<Text("...>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Text("%c %cl", %composer, 0)
} else {
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTestsNoSource.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTestsNoSource.kt
index 9b4fca9..8ccb434 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTestsNoSource.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTestsNoSource.kt
@@ -33,7 +33,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)")
if (%changed !== 0 || !%composer.skipping) {
A(a, %composer, 0)
A(b, %composer, 0)
@@ -86,7 +87,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)")
if (%changed !== 0 || !%composer.skipping) {
W(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -97,7 +99,7 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
A(%composer, 0)
} else {
@@ -121,7 +123,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)")
if (%changed !== 0 || !%composer.skipping) {
IW({ %composer: Composer?, %changed: Int ->
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/DefaultParamTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/DefaultParamTransformTests.kt
index 1c8d410..0f07375 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/DefaultParamTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/DefaultParamTransformTests.kt
@@ -63,7 +63,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(1)>,<B()>,<B(2)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(1)>,<B()>,<B(2)>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
A(1, %composer, 0b0110)
B(0, %composer, 0, 0b0001)
@@ -96,7 +97,8 @@
"""
@Composable
fun Example(foo: Foo, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)P(0:Foo):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)P(0:Foo):Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -117,7 +119,8 @@
}
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<Exampl...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<Exampl...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
Example(Foo(0), %composer, 0, 0b0001)
} else {
@@ -145,7 +148,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(0,>,<A(a>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(0,>,<A(a>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
A(0, 1, 2, 0, 0, %composer, 0b000110110110, 0b00011000)
A(0, 0, 2, 0, 0, %composer, 0b000110000110, 0b00011010)
@@ -173,7 +177,8 @@
"""
@Composable
fun Test(x: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%default and 0b0001 === 0 && %composer.changed(x)) 0b0100 else 0b0010
@@ -217,7 +222,8 @@
"""
@Composable
fun A(a: Int, b: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A):Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -331,7 +337,8 @@
"""
@Composable
fun Example(a00: Int, a01: Int, a02: Int, a03: Int, a04: Int, a05: Int, a06: Int, a07: Int, a08: Int, a09: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int, a23: Int, a24: Int, a25: Int, a26: Int, a27: Int, a28: Int, a29: Int, a30: Int, %composer: Composer?, %changed: Int, %changed1: Int, %changed2: Int, %changed3: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val %dirty = %changed
val %dirty1 = %changed1
val %dirty2 = %changed2
@@ -703,7 +710,8 @@
"""
@Composable
fun Example(a00: Int, a01: Int, a02: Int, a03: Int, a04: Int, a05: Int, a06: Int, a07: Int, a08: Int, a09: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int, a23: Int, a24: Int, a25: Int, a26: Int, a27: Int, a28: Int, a29: Int, a30: Int, a31: Int, %composer: Composer?, %changed: Int, %changed1: Int, %changed2: Int, %changed3: Int, %default: Int, %default1: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val %dirty = %changed
val %dirty1 = %changed1
val %dirty2 = %changed2
@@ -1085,7 +1093,8 @@
"""
@Composable
fun Example(a00: Int, a01: Int, a02: Int, a03: Int, a04: Int, a05: Int, a06: Int, a07: Int, a08: Int, a09: Foo?, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, a16: Int, a17: Int, a18: Int, a19: Int, a20: Int, a21: Int, a22: Int, a23: Int, a24: Int, a25: Int, a26: Int, a27: Int, a28: Int, a29: Int, a30: Int, a31: Foo?, %composer: Composer?, %changed: Int, %changed1: Int, %changed2: Int, %changed3: Int, %default: Int, %default1: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val %dirty = %changed
val %dirty1 = %changed1
val %dirty2 = %changed2
@@ -1419,7 +1428,8 @@
@NonRestartableComposable
@Composable
fun foo(x: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer.startReplaceableGroup(<>, "C(foo):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(foo):Test.kt")
if (%default and 0b0001 !== 0) {
x = 0
}
@@ -1432,7 +1442,8 @@
@NonRestartableComposable
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<foo()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<foo()>:Test.kt")
foo(0, %composer, 0b01110000 and %changed shl 0b0011, 0b0001)
%composer.endReplaceableGroup()
}
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionBodySkippingTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionBodySkippingTransformTests.kt
index 44c68ac..de0dc0e 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionBodySkippingTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionBodySkippingTransformTests.kt
@@ -72,7 +72,8 @@
"""
@Composable
fun Test(x: Int, y: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<Wrap>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<Wrap>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -92,14 +93,17 @@
y = 0
}
used(y)
- Wrap(composableLambda(%composer, <>, true, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ Wrap(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
if (x > 0) {
- %composer.startReplaceableGroup(<>, "<A(x)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(x)>")
A(x, 0, %composer, 0b1110 and %dirty, 0b0010)
%composer.endReplaceableGroup()
} else {
- %composer.startReplaceableGroup(<>, "<A(x)>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A(x)>")
A(x, 0, %composer, 0b1110 and %dirty, 0b0010)
%composer.endReplaceableGroup()
}
@@ -136,7 +140,8 @@
Example(class <no name provided> : A {
@Composable
override fun compute(it: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(compute)<comput...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(compute)<comput...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
@@ -186,7 +191,8 @@
"""
@Composable
fun Button(colors: ButtonColors, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Button)<getCol...>,<Text("...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Button)<getCol...>,<Text("...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(colors)) 0b0100 else 0b0010
@@ -202,12 +208,14 @@
}
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<Button>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<Button>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
Button(class <no name provided> : ButtonColors {
@Composable
override fun getColor(%composer: Composer?, %changed: Int): Color {
- %composer.startReplaceableGroup(<>, "C(getColor)<condit...>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(getColor)<condit...>:Test.kt")
val tmp0 = if (condition(%composer, 0)) {
Companion.Red
} else {
@@ -308,7 +316,8 @@
"""
@Composable
fun RowColumnImpl(orientation: LayoutOrientation, modifier: Modifier?, arrangement: Vertical?, crossAxisAlignment: Horizontal?, crossAxisSize: SizeMode?, content: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(RowColumnImpl)P(5,4!1,2,3)<conten...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(RowColumnImpl)P(5,4!1,2,3)<conten...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -376,7 +385,8 @@
}
@Composable
fun Column(modifier: Modifier?, verticalArrangement: Vertical?, horizontalGravity: Horizontal?, content: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Column)P(2,3,1)<RowCol...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Column)P(2,3,1)<RowCol...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -448,7 +458,8 @@
"""
@Composable
fun SimpleBox(modifier: Modifier?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(SimpleBox):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(SimpleBox):Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -484,7 +495,8 @@
"""
@Composable
fun Example(a: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%default and 0b0001 === 0 && %composer.changed(a)) 0b0100 else 0b0010
@@ -531,7 +543,8 @@
"""
@Composable
fun Example(a: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<Inner(...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<Inner(...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
@@ -539,7 +552,8 @@
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
@Composable
fun Inner(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Inner)<A(a)>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Inner)<A(a)>:Test.kt")
A(a, %composer, 0b1110 and %dirty)
%composer.endReplaceableGroup()
}
@@ -577,11 +591,13 @@
@Composable
@NonRestartableComposable
fun Example(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(Example)<Call()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Example)<Call()>:Test.kt")
Call(%composer, 0)
val tmp0_iterator = 0 .. 1.iterator()
while (tmp0_iterator.hasNext()) {
- %composer.startReplaceableGroup(<>, "<Call()>,<Call()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<Call()>,<Call()>")
val index = tmp0_iterator.next()
Call(%composer, 0)
if (condition()) {
@@ -621,7 +637,8 @@
"""
@Composable
fun SimpleBox(modifier: Modifier?, shape: Shape?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(SimpleBox):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(SimpleBox):Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -680,7 +697,8 @@
"""
@Composable
fun SimpleBox(modifier: Modifier?, content: Function2<Composer, Int, Unit>?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(SimpleBox)P(1)<conten...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(SimpleBox)P(1)<conten...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -717,7 +735,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -746,7 +765,8 @@
"""
val foo: Function4<Int, Foo, Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-1
internal object ComposableSingletons%TestKt {
- val lambda-1: Function4<Int, Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<A(x)>,<B(y)>:") { x: Int, y: Foo, %composer: Composer?, %changed: Int ->
+ val lambda-1: Function4<Int, Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, y: Foo, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A(x)>,<B(y)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -781,7 +801,8 @@
"""
val foo: Function4<Int, Foo, Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-1
internal object ComposableSingletons%TestKt {
- val lambda-1: Function4<Int, Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<A(x)>,<B(y)>:") { x: Int, y: Foo, %composer: Composer?, %changed: Int ->
+ val lambda-1: Function4<Int, Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, y: Foo, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A(x)>,<B(y)>:Test.kt")
A(x, %composer, 0b1110 and %changed)
B(y, %composer, 0b1000)
}
@@ -806,7 +827,8 @@
"""
@Composable
fun SomeThing(content: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(SomeThing)<conten...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(SomeThing)<conten...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
@@ -822,7 +844,8 @@
}
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<SomeTh...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<SomeTh...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
SomeThing(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -833,7 +856,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
val id = object
} else {
@@ -857,7 +881,8 @@
"""
@Composable
fun B(values: IntArray, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B):Test.kt")
val %dirty = %changed
%composer.startReplaceableGroup(values.size)
val tmp0_iterator = values.iterator()
@@ -896,7 +921,8 @@
"""
@Composable
fun B(values: Array<out Foo>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B):Test.kt")
val %dirty = %changed
%composer.startReplaceableGroup(values.size)
val tmp0_iterator = values.iterator()
@@ -935,7 +961,8 @@
"""
@Composable
fun B(values: Array<out Foo>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B):Test.kt")
print(values)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
B(*values, %composer, %changed or 0b0001)
@@ -965,7 +992,8 @@
var counter: Int = 0
@Composable
fun A(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A):Test.kt")
if (%changed and 0b0001 !== 0 || !%composer.skipping) {
print("hello world")
} else {
@@ -978,7 +1006,8 @@
}
@Composable
fun B(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B):Test.kt")
print(counter)
val tmp0_rcvr = <this>
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
@@ -1006,7 +1035,8 @@
"""
@Composable
fun Example(a: Int, b: Int, c: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<makeIn...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<makeIn...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -1075,7 +1105,8 @@
"""
@Composable
fun Wrap(y: Int, content: Function3<@[ParameterName(name = 'x')] Int, Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Wrap)P(1)<conten...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Wrap)P(1)<conten...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
@@ -1094,7 +1125,8 @@
}
@Composable
fun Test(x: Int, y: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<Wrap(1...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<Wrap(1...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -1114,7 +1146,8 @@
y = 0
}
used(y)
- Wrap(10, composableLambda(%composer, <>, true, "C<A(x)>:Test.kt") { it: Int, %composer: Composer?, %changed: Int ->
+ Wrap(10, composableLambda(%composer, <>, true) { it: Int, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(it)) 0b0100 else 0b0010
@@ -1151,7 +1184,8 @@
"""
@Composable
fun Test(x: Int, y: Int, %composer: Composer?, %changed: Int, %default: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Test)<A(x,>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x,>:Test.kt")
if (%default and 0b0001 !== 0) {
x = 0
}
@@ -1179,7 +1213,8 @@
"""
val test: Function3<Int, Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-1
internal object ComposableSingletons%TestKt {
- val lambda-1: Function3<Int, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C<A(x)>:") { x: Int, %composer: Composer?, %changed: Int ->
+ val lambda-1: Function3<Int, Composer, Int, Unit> = composableLambdaInstance(<>, false) { x: Int, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -1205,7 +1240,8 @@
"""
@Composable
fun Test(x: Int, %composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(Test)<A()>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Test)<A()>:Test.kt")
val tmp0 = A(0, 0, %composer, 0, 0b0011)
%composer.endReplaceableGroup()
return tmp0
@@ -1226,7 +1262,8 @@
"""
@Composable
fun Test(x: Int, y: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(y>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(y>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -1269,7 +1306,8 @@
"""
@Composable
fun CanSkip(a: Int, b: Foo?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(CanSkip):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(CanSkip):Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -1308,7 +1346,8 @@
}
@Composable
fun CannotSkip(a: Int, b: Foo, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(CannotSkip):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(CannotSkip):Test.kt")
used(a)
used(b)
print("Hello World")
@@ -1318,7 +1357,8 @@
}
@Composable
fun NoParams(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(NoParams):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(NoParams):Test.kt")
if (%changed !== 0 || !%composer.skipping) {
print("Hello World")
} else {
@@ -1345,7 +1385,8 @@
"""
@Composable
fun Bar.CanSkip(b: Foo?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(CanSkip):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(CanSkip):Test.kt")
val %dirty = %changed
if (%default.inv() and 0b0001 !== 0 || %dirty and 0b0001 !== 0 || !%composer.skipping) {
if (%changed and 0b0001 === 0 || %composer.defaultsInvalid) {
@@ -1387,7 +1428,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A()>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A()>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
A(%composer, 0)
} else {
@@ -1414,7 +1456,8 @@
"""
@Composable
fun Test(x: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -1455,7 +1498,8 @@
"""
@Composable
fun A(text: String, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<B(text...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<B(text...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(text)) 0b0100 else 0b0010
@@ -1471,7 +1515,8 @@
}
@Composable
fun B(text: String, color: Color, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B)P(1,0:Color):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B)P(1,0:Color):Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -1563,7 +1608,8 @@
"""
@Composable
fun A(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<D>,<C({})>,<C(stab...>,<C(16.d...>,<C(Dp(1...>,<C(16.d...>,<C(norm...>,<C(Int....>,<C(stab...>,<C(Modi...>,<C(Foo....>,<C(cons...>,<C(123)>,<C(123>,<C(x)>,<C(x>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<D>,<C({})>,<C(stab...>,<C(16.d...>,<C(Dp(1...>,<C(16.d...>,<C(norm...>,<C(Int....>,<C(stab...>,<C(Modi...>,<C(Foo....>,<C(cons...>,<C(123)>,<C(123>,<C(x)>,<C(x>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val x = 123
D(ComposableSingletons%TestKt.lambda-1, %composer, 0)
@@ -1592,7 +1638,8 @@
}
@Composable
fun B(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(B)<C(Math...>,<C(Math...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(B)<C(Math...>,<C(Math...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
C(random(), %composer, 0)
C(random() / 100.0f, %composer, 0)
@@ -1604,7 +1651,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -1628,7 +1676,8 @@
"""
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<D>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<D>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
D(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -1639,7 +1688,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -1664,7 +1714,8 @@
"""
@Composable
fun Test(x: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -1701,7 +1752,8 @@
"""
@Composable
fun Test(x: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<I()>,<A(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<I()>,<A(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%default and 0b0001 === 0 && %composer.changed(x)) 0b0100 else 0b0010
@@ -1746,7 +1798,8 @@
"""
@Composable
fun Test(x: Foo, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
A(x, %composer, 0b1000)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
Test(x, %composer, %changed or 0b0001)
@@ -1770,7 +1823,8 @@
"""
@Composable
fun Test(x: Foo?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%default and 0b0001 === 0 && %composer.changed(x)) 0b0100 else 0b0010
@@ -1815,7 +1869,8 @@
"""
@Composable
fun Test(a: Int, b: Boolean, c: Int, d: Foo?, e: List<Int>?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(a,>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(a,>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -1887,7 +1942,8 @@
"""
@Composable
fun X(x: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(X)<X(x>,<X(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(X)<X(x>,<X(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -1948,7 +2004,8 @@
itemsIndexed(items, ComposableSingletons%TestKt.lambda-1)
}
internal object ComposableSingletons%TestKt {
- val lambda-1: @[ExtensionFunctionType] Function5<LazyItemScope, Int, User?, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { index: Int, user: User?, %composer: Composer?, %changed: Int ->
+ val lambda-1: @[ExtensionFunctionType] Function5<LazyItemScope, Int, User?, Composer, Int, Unit> = composableLambdaInstance(<>, false) { index: Int, user: User?, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b0001010000000001 xor 0b010000000000 !== 0 || !%composer.skipping) {
print("Hello World")
} else {
@@ -1974,7 +2031,8 @@
"""
@Composable
fun Unstable.Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<doSome...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<doSome...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
@@ -1990,7 +2048,8 @@
}
@Composable
fun doSomething(x: Unstable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(doSomething):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(doSomething):Test.kt")
if (%changed and 0b0001 !== 0 || !%composer.skipping) {
} else {
%composer.skipToGroupEnd()
@@ -2074,7 +2133,8 @@
"""
@Composable
fun A(x: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<B(>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<B(>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -2118,14 +2178,16 @@
val stableUnused: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-3
val stableUsed: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-4
internal object ComposableSingletons%TestKt {
- val lambda-1: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { %composer: Composer?, %changed: Int ->
+ val lambda-1: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b01010001 xor 0b00010000 !== 0 || !%composer.skipping) {
Unit
} else {
%composer.skipToGroupEnd()
}
}
- val lambda-2: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { %composer: Composer?, %changed: Int ->
+ val lambda-2: @[ExtensionFunctionType] Function3<Foo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(%this%null)) 0b0100 else 0b0010
@@ -2136,14 +2198,16 @@
%composer.skipToGroupEnd()
}
}
- val lambda-3: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { %composer: Composer?, %changed: Int ->
+ val lambda-3: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b01010001 xor 0b00010000 !== 0 || !%composer.skipping) {
Unit
} else {
%composer.skipToGroupEnd()
}
}
- val lambda-4: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { %composer: Composer?, %changed: Int ->
+ val lambda-4: @[ExtensionFunctionType] Function3<StableFoo, Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(%this%null)) 0b0100 else 0b0010
@@ -2179,19 +2243,22 @@
"""
@Composable
fun A(x: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<Provid...>,<B(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<Provid...>,<B(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
}
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
- Provide(composableLambda(%composer, <>, true, "C<Provid...>,<B(x,>:Test.kt") { y: Int, %composer: Composer?, %changed: Int ->
+ Provide(composableLambda(%composer, <>, true) { y: Int, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<Provid...>,<B(x,>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(y)) 0b0100 else 0b0010
}
if (%dirty and 0b01011011 xor 0b00010010 !== 0 || !%composer.skipping) {
- Provide(composableLambda(%composer, <>, true, "C<B(x,>:Test.kt") { z: Int, %composer: Composer?, %changed: Int ->
+ Provide(composableLambda(%composer, <>, true) { z: Int, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<B(x,>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(z)) 0b0100 else 0b0010
@@ -2235,7 +2302,8 @@
"""
@Composable
fun A(x: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<foo(x)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<foo(x)>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -2243,7 +2311,8 @@
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
@Composable
fun foo(y: Int, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(foo)<B(x,>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(foo)<B(x,>:Test.kt")
B(x, y, %composer, 0b1110 and %dirty or 0b01110000 and %changed shl 0b0011)
%composer.endReplaceableGroup()
}
@@ -2322,7 +2391,8 @@
"""
@Composable
fun Example(a00: Int, a01: Int, a02: Int, a03: Int, a04: Int, a05: Int, a06: Int, a07: Int, a08: Int, a09: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, %composer: Composer?, %changed: Int, %changed1: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<Exampl...>,<Exampl...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<Exampl...>,<Exampl...>:Test.kt")
val %dirty = %changed
val %dirty1 = %changed1
if (%default and 0b0001 !== 0) {
@@ -2525,7 +2595,8 @@
"""
@Composable
fun Example(a00: Int, a01: Int, a02: Int, a03: Int, a04: Int, a05: Int, a06: Int, a07: Int, a08: Int, a09: Int, a10: Int, a11: Int, a12: Int, a13: Int, a14: Int, a15: Int, %composer: Composer?, %changed: Int, %changed1: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<Exampl...>,<Exampl...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<Exampl...>,<Exampl...>:Test.kt")
val %dirty = %changed
val %dirty1 = %changed1
if (%default and 0b0001 !== 0) {
@@ -2696,17 +2767,17 @@
val current: Int
@Composable @ReadOnlyComposable @JvmName(name = "getCurrent")
get() {
- %composer.startReplaceableGroup(<>, "C:Test.kt")
+ sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
val tmp0 = %composer.hashCode()
- %composer.endReplaceableGroup()
+ sourceInformationMarkerEnd(%composer)
return tmp0
}
@ReadOnlyComposable
@Composable
fun getHashCode(%composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(getHashCode):Test.kt")
+ sourceInformationMarkerStart(%composer, <>, "C(getHashCode):Test.kt")
val tmp0 = %composer.hashCode()
- %composer.endReplaceableGroup()
+ sourceInformationMarkerEnd(%composer)
return tmp0
}
static val %stable: Int = 0
@@ -2714,9 +2785,9 @@
@ReadOnlyComposable
@Composable
fun getHashCode(%composer: Composer?, %changed: Int): Int {
- %composer.startReplaceableGroup(<>, "C(getHashCode):Test.kt")
+ sourceInformationMarkerStart(%composer, <>, "C(getHashCode):Test.kt")
val tmp0 = %composer.hashCode()
- %composer.endReplaceableGroup()
+ sourceInformationMarkerEnd(%composer)
return tmp0
}
"""
@@ -2743,7 +2814,8 @@
"""
@Composable
fun Example(wontChange: Int, mightChange: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)P(1)<curren...>,<A(wont...>,<A(migh...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)P(1)<curren...>,<A(wont...>,<A(migh...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -2794,7 +2866,8 @@
"""
@Composable
fun Example(content: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<invoke...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<invoke...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
@@ -2854,7 +2927,8 @@
"""
@Composable
fun Box2(modifier: Modifier?, paddingStart: Dp, content: Function2<Composer, Int, Unit>?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Box2)P(1,2:c#ui.unit.Dp)<conten...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Box2)P(1,2:c#ui.unit.Dp)<conten...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -2902,7 +2976,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -2933,14 +3008,16 @@
"""
@Composable
fun Test(cond: Boolean, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(cond)) 0b0100 else 0b0010
}
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
if (cond) {
- %composer.startReplaceableGroup(<>, "<A()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>")
A(%composer, 0)
%composer.endReplaceableGroup()
} else {
@@ -2948,7 +3025,8 @@
%composer.endReplaceableGroup()
}
if (cond) {
- %composer.startReplaceableGroup(<>, "<B()>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<B()>")
B(%composer, 0)
%composer.endReplaceableGroup()
} else {
@@ -2991,7 +3069,8 @@
"""
@Composable
fun Unskippable(a: Unstable, b: Stable, c: MaybeStable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Unskippable):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Unskippable):Test.kt")
used(a)
%composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
Unskippable(a, b, c, %composer, %changed or 0b0001)
@@ -2999,7 +3078,8 @@
}
@Composable
fun Skippable1(a: Unstable, b: Stable, c: MaybeStable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Skippable1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Skippable1):Test.kt")
val %dirty = %changed
if (%changed and 0b01110000 === 0) {
%dirty = %dirty or if (%composer.changed(b)) 0b00100000 else 0b00010000
@@ -3015,7 +3095,8 @@
}
@Composable
fun Skippable2(a: Unstable, b: Stable, c: MaybeStable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Skippable2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Skippable2):Test.kt")
val %dirty = %changed
if (%changed and 0b001110000000 === 0) {
%dirty = %dirty or if (%composer.changed(c)) 0b000100000000 else 0b10000000
@@ -3031,7 +3112,8 @@
}
@Composable
fun Skippable3(a: Unstable, b: Stable, c: MaybeStable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Skippable3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Skippable3):Test.kt")
if (%changed and 0b0001 !== 0 || !%composer.skipping) {
} else {
%composer.skipToGroupEnd()
@@ -3061,7 +3143,8 @@
"""
@Composable
fun MaybeStable.example(x: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(example):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(example):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(<this>)) 0b0100 else 0b0010
@@ -3081,7 +3164,8 @@
}
val example: @[ExtensionFunctionType] Function4<MaybeStable, Int, Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-1
internal object ComposableSingletons%TestKt {
- val lambda-1: @[ExtensionFunctionType] Function4<MaybeStable, Int, Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { it: Int, %composer: Composer?, %changed: Int ->
+ val lambda-1: @[ExtensionFunctionType] Function4<MaybeStable, Int, Composer, Int, Unit> = composableLambdaInstance(<>, false) { it: Int, %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(%this%null)) 0b0100 else 0b0010
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt
index 838f9bf..1946801 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/LambdaMemoizationTransformTests.kt
@@ -36,7 +36,8 @@
@StabilityInferred(parameters = 0)
class A {
val b: String = ""
- val c: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, true, "C:") { %composer: Composer?, %changed: Int ->
+ val c: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
print(b)
} else {
@@ -66,23 +67,28 @@
"""
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example):Test.kt")
if (%changed !== 0 || !%composer.skipping) {
@Composable
fun A(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(A):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(A):Test.kt")
%composer.endReplaceableGroup()
}
@Composable
fun B(content: Function2<Composer, Int, Unit>, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(B)<conten...>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(B)<conten...>:Test.kt")
content(%composer, 0b1110 and %changed)
%composer.endReplaceableGroup()
}
@Composable
fun C(%composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(C)<B>:Test.kt")
- B(composableLambda(%composer, <>, false, "C<A()>:Test.kt") { %composer: Composer?, %changed: Int ->
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(C)<B>:Test.kt")
+ B(composableLambda(%composer, <>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<A()>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
A(%composer, 0)
} else {
@@ -120,10 +126,12 @@
"""
@Composable
fun A(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<B>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<B>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
<<LOCALDELPROP>>
- B(composableLambda(%composer, <>, true, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ B(composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
print(<get-x>())
} else {
@@ -157,14 +165,16 @@
val foo: Function2<Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-1
val bar: Function2<Composer, Int, Unit> = ComposableSingletons%TestKt.lambda-2
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
%composer.skipToGroupEnd()
}
}
- val lambda-2: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:") { %composer: Composer?, %changed: Int ->
+ val lambda-2: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -192,7 +202,8 @@
"""
@Composable
fun A(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<B(foo)>,<B(bar)>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<B(foo)>,<B(bar)>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val foo = ComposableSingletons%TestKt.lambda-1
val bar = ComposableSingletons%TestKt.lambda-2
@@ -206,14 +217,16 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
%composer.skipToGroupEnd()
}
}
- val lambda-2: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-2: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -240,7 +253,8 @@
"""
@Composable
fun A(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(A)<B>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(A)<B>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
B(ComposableSingletons%TestKt.lambda-1, %composer, 0)
} else {
@@ -251,7 +265,8 @@
}
}
internal object ComposableSingletons%TestKt {
- val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false, "C:Test.kt") { %composer: Composer?, %changed: Int ->
+ val lambda-1: Function2<Composer, Int, Unit> = composableLambdaInstance(<>, false) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Unit
} else {
@@ -282,7 +297,8 @@
"""
@Composable
fun Test(enabled: Boolean, content: Function2<Composer, Int, Unit>?, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)P(1)<Wrap(c...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)P(1)<Wrap(c...>:Test.kt")
val %dirty = %changed
if (%default and 0b0001 !== 0) {
%dirty = %dirty or 0b0110
@@ -296,7 +312,8 @@
}
if (%dirty and 0b01011011 xor 0b00010010 !== 0 || !%composer.skipping) {
if (%default and 0b0010 !== 0) {
- content = composableLambda(%composer, <>, true, "C<Displa...>:Test.kt") { %composer: Composer?, %changed: Int ->
+ content = composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<Displa...>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Display("%enabled", %composer, 0)
} else {
@@ -337,13 +354,15 @@
"""
@Composable
fun Test(enabled: Boolean, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<Wrap(c...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<Wrap(c...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(enabled)) 0b0100 else 0b0010
}
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
- val content = composableLambda(%composer, <>, true, "C<Displa...>:Test.kt") { %composer: Composer?, %changed: Int ->
+ val content = composableLambda(%composer, <>, true) { %composer: Composer?, %changed: Int ->
+ sourceInformation(%composer, "C<Displa...>:Test.kt")
if (%changed and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
Display("%enabled", %composer, 0)
} else {
@@ -388,7 +407,8 @@
"""
@Composable
fun TestLambda(content: Function0<Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(TestLambda):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(TestLambda):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
@@ -404,7 +424,8 @@
}
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<TestLa...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<TestLa...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
TestLambda({
println("Doesn't capture")
@@ -440,7 +461,8 @@
"""
@Composable
fun TestLambda(content: Function0<Unit>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(TestLambda):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(TestLambda):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
@@ -456,7 +478,8 @@
}
@Composable
fun Test(a: String, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<{>,<TestLa...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<{>,<TestLa...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
index 51532ad..e0863c1 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
@@ -62,7 +62,8 @@
@Composable
@NonRestartableComposable
fun app(x: Boolean, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(app)<rememb...>:Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(app)<rememb...>:Test.kt")
val a = if (x) {
%composer.startReplaceableGroup(<>)
val tmp0_group = %composer.cache(false) {
@@ -105,7 +106,8 @@
"""
@Composable
fun <T> loadResourceInternal(key: String, pendingResource: T?, failedResource: T?, %composer: Composer?, %changed: Int, %default: Int): Boolean {
- %composer.startReplaceableGroup(<>, "C(loadResourceInternal)P(1,2):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(loadResourceInternal)P(1,2):Test.kt")
if (%default and 0b0010 !== 0) {
pendingResource = null
}
@@ -147,7 +149,8 @@
"""
@Composable
fun test1(x: KnownStable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(test1):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(test1):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -166,7 +169,8 @@
}
@Composable
fun test2(x: KnownUnstable, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(test2):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(test2):Test.kt")
%composer.cache(%composer.changed(x)) {
val tmp0_return = 1
tmp0_return
@@ -177,7 +181,8 @@
}
@Composable
fun test3(x: Uncertain, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(test3):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(test3):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -227,7 +232,8 @@
@Composable
@NonRestartableComposable
fun test1(x: KnownStable, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(test1):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(test1):Test.kt")
%composer.cache(%changed and 0b1110 xor 0b0110 > 4 && %composer.changed(x) || %changed and 0b0110 === 0b0100) {
val tmp0_return = 1
tmp0_return
@@ -237,7 +243,8 @@
@Composable
@NonRestartableComposable
fun test2(x: KnownUnstable, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(test2):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(test2):Test.kt")
%composer.cache(%composer.changed(x)) {
val tmp0_return = 1
tmp0_return
@@ -247,7 +254,8 @@
@Composable
@NonRestartableComposable
fun test3(x: Uncertain, %composer: Composer?, %changed: Int) {
- %composer.startReplaceableGroup(<>, "C(test3):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(test3):Test.kt")
%composer.cache(%changed and 0b1110 xor 0b0110 > 4 && %composer.changed(x) || %changed and 0b0110 === 0b0100) {
val tmp0_return = 1
tmp0_return
@@ -269,7 +277,8 @@
"""
@Composable
fun rememberFoo(a: Int, b: Int, %composer: Composer?, %changed: Int): Foo {
- %composer.startReplaceableGroup(<>, "C(rememberFoo):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(rememberFoo):Test.kt")
val tmp0 = %composer.cache(%changed and 0b1110 xor 0b0110 > 4 && %composer.changed(a) || %changed and 0b0110 === 0b0100 or %changed and 0b01110000 xor 0b00110000 > 32 && %composer.changed(b) || %changed and 0b00110000 === 0b00100000) {
val tmp0_return = Foo(a, b)
tmp0_return
@@ -298,7 +307,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A()>,<rememb...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A()>,<rememb...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val foo = %composer.cache(false) {
val tmp0_return = Foo()
@@ -340,7 +350,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val a = someInt()
val b = someInt()
@@ -373,7 +384,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<CInt()...>,<rememb...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<CInt()...>,<rememb...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val foo = remember(CInt(%composer, 0), {
val tmp0_return = Foo()
@@ -408,7 +420,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<curren...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<curren...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val bar = compositionLocalBar.current
val foo = %composer.cache(%composer.changed(bar)) {
@@ -443,7 +456,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<curren...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<curren...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val foo = %composer.cache(%composer.changed(compositionLocalBar.current)) {
val tmp0_return = Foo()
@@ -475,7 +489,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A()>,<rememb...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A()>,<rememb...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
A(%composer, 0)
val foo = remember({
@@ -510,7 +525,8 @@
"""
@Composable
fun Test(condition: Boolean, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A()>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A()>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
@@ -556,14 +572,16 @@
"""
@Composable
fun Test(condition: Boolean, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(condition)) 0b0100 else 0b0010
}
if (%dirty and 0b1011 xor 0b0010 !== 0 || !%composer.skipping) {
if (condition) {
- %composer.startReplaceableGroup(<>, "<A()>,<rememb...>")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "<A()>,<rememb...>")
A(%composer, 0)
val foo = remember({
val tmp0_return = Foo()
@@ -602,7 +620,8 @@
"""
@Composable
fun Test(items: List<Int>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)*<rememb...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)*<rememb...>:Test.kt")
val tmp0_iterator = items.iterator()
while (tmp0_iterator.hasNext()) {
val item = tmp0_iterator.next()
@@ -640,7 +659,8 @@
"""
@Composable
fun Test(items: List<Int>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)*<rememb...>,<A()>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)*<rememb...>,<A()>:Test.kt")
val tmp0_iterator = items.iterator()
while (tmp0_iterator.hasNext()) {
val item = tmp0_iterator.next()
@@ -674,7 +694,8 @@
"""
@Composable
fun Test(items: List<Int>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val foo = %composer.cache(false) {
val tmp0_return = Foo()
tmp0_return
@@ -702,7 +723,8 @@
"""
@Composable
fun Test(a: Int, b: Int, c: Bar, d: Boolean, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
@@ -746,7 +768,8 @@
"""
@Composable
fun Test(items: Array<Bar>, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<rememb...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<rememb...>:Test.kt")
val foo = remember(*items, {
val tmp0_return = Foo()
tmp0_return
@@ -774,7 +797,8 @@
"""
@Composable
fun Test(inlineInt: InlineInt, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)P(0:InlineInt):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)P(0:InlineInt):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(inlineInt.value)) 0b0100 else 0b0010
@@ -815,7 +839,8 @@
"""
@Composable
fun Test(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
if (%changed !== 0 || !%composer.skipping) {
val a = someInt()
val b = someInt()
@@ -855,7 +880,8 @@
"""
@Composable
fun Test(a: Int, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test):Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(a)) 0b0100 else 0b0010
@@ -892,7 +918,8 @@
"""
@Composable
fun Test(a: Int, %composer: Composer?, %changed: Int): Foo {
- %composer.startReplaceableGroup(<>, "C(Test):Test.kt")
+ %composer.startReplaceableGroup(<>)
+ sourceInformation(%composer, "C(Test):Test.kt")
val b = someInt()
val tmp0 = %composer.cache(%changed and 0b1110 xor 0b0110 > 4 && %composer.changed(a) || %changed and 0b0110 === 0b0100 or %composer.changed(b)) {
val tmp0_return = Foo(a, b)
@@ -921,7 +948,8 @@
"""
@Composable
fun Test(a: Int, %composer: Composer?, %changed: Int, %default: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<rememb...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<rememb...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%default and 0b0001 === 0 && %composer.changed(a)) 0b0100 else 0b0010
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/StabilityPropagationTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/StabilityPropagationTransformTests.kt
index b434332..a056dcd 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/StabilityPropagationTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/StabilityPropagationTransformTests.kt
@@ -61,7 +61,8 @@
"""
@Composable
fun Test(x: Foo, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
val %dirty = %changed
if (%changed and 0b1110 === 0) {
%dirty = %dirty or if (%composer.changed(x)) 0b0100 else 0b0010
@@ -102,7 +103,8 @@
"""
@Composable
fun Test(x: Foo, %composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Test)<A(x)>,<A(Foo(...>,<rememb...>,<A(reme...>:Test.kt")
A(x, %composer, 0b1000)
A(Foo(0), %composer, 0b1000)
A(remember({
@@ -130,7 +132,8 @@
"""
@Composable
fun Example(%composer: Composer?, %changed: Int) {
- %composer = %composer.startRestartGroup(<>, "C(Example)<A(list...>:Test.kt")
+ %composer = %composer.startRestartGroup(<>)
+ sourceInformation(%composer, "C(Example)<A(list...>:Test.kt")
if (%changed !== 0 || !%composer.skipping) {
A(listOf("a"), %composer, 0)
} else {
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/KtxNameConventions.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/KtxNameConventions.kt
index 4b9c724..4db291b 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/KtxNameConventions.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/KtxNameConventions.kt
@@ -12,4 +12,7 @@
val STARTRESTARTGROUP = Name.identifier("startRestartGroup")
val ENDRESTARTGROUP = Name.identifier("endRestartGroup")
val UPDATE_SCOPE = Name.identifier("updateScope")
+ val SOURCEINFORMATION = "sourceInformation"
+ val SOURCEINFORMATIONMARKERSTART = "sourceInformationMarkerStart"
+ val SOURCEINFORMATIONMARKEREND = "sourceInformationMarkerEnd"
}
\ No newline at end of file
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 56ec08a..c448eee 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
@@ -515,13 +515,6 @@
}
}
- private val startReplaceableSourceFunction by guardedLazy {
- composerIrClass.functions
- .first {
- it.name.identifier == "startReplaceableGroup" && it.valueParameters.size == 2
- }
- }
-
private val endReplaceableFunction by guardedLazy {
composerIrClass.functions
.first {
@@ -550,13 +543,6 @@
}
}
- private val startMovableSourceFunction by guardedLazy {
- composerIrClass.functions
- .first {
- it.name.identifier == "startMovableGroup" && it.valueParameters.size == 3
- }
- }
-
private val endMovableFunction by guardedLazy {
composerIrClass.functions
.first {
@@ -572,13 +558,6 @@
}
}
- private val startRestartGroupSourceFunction by guardedLazy {
- composerIrClass.functions
- .first {
- it.name == KtxNameConventions.STARTRESTARTGROUP && it.valueParameters.size == 2
- }
- }
-
private val endRestartGroupFunction by guardedLazy {
composerIrClass
.functions
@@ -587,6 +566,24 @@
}
}
+ private val sourceInformationFunction by guardedLazy {
+ getTopLevelFunctions(
+ ComposeFqNames.fqNameFor(KtxNameConventions.SOURCEINFORMATION)
+ ).map { it.owner }.first()
+ }
+
+ private val sourceInformationMarkerStartFunction by guardedLazy {
+ getTopLevelFunctions(
+ ComposeFqNames.fqNameFor(KtxNameConventions.SOURCEINFORMATIONMARKERSTART)
+ ).map { it.owner }.first()
+ }
+
+ private val sourceInformationMarkerEndFunction by guardedLazy {
+ getTopLevelFunctions(
+ ComposeFqNames.fqNameFor(KtxNameConventions.SOURCEINFORMATIONMARKEREND)
+ ).map { it.owner }.first()
+ }
+
private val IrType.arguments: List<IrTypeArgument>
get() = (this as? IrSimpleType)?.arguments.orEmpty()
@@ -768,7 +765,7 @@
@OptIn(ObsoleteDescriptorBasedAPI::class)
private fun IrFunction.shouldElideGroups(): Boolean {
- return (!collectSourceInformation && descriptor.hasReadonlyComposableAnnotation()) ||
+ return descriptor.hasReadonlyComposableAnnotation() ||
descriptor.hasExplicitGroupsAnnotation()
}
@@ -822,17 +819,31 @@
body.startOffset,
body.endOffset,
listOfNotNull(
- if (!elideGroups)
- irStartReplaceableGroup(
- body,
- scope,
- declaration.irSourceKey()
- )
- else
- null,
+ when {
+ !elideGroups ->
+ irStartReplaceableGroup(
+ body,
+ scope,
+ declaration.irSourceKey()
+ )
+ collectSourceInformation &&
+ !declaration.descriptor.hasExplicitGroupsAnnotation() ->
+ irSourceInformationMarkerStart(
+ body,
+ scope,
+ declaration.irSourceKey()
+ )
+ else -> null
+ },
*bodyPreamble.statements.toTypedArray(),
*transformed.statements.toTypedArray(),
- if (!elideGroups) irEndReplaceableGroup() else null,
+ when {
+ !elideGroups -> irEndReplaceableGroup()
+ collectSourceInformation &&
+ !declaration.descriptor.hasExplicitGroupsAnnotation() ->
+ irSourceInformationMarkerEnd(body)
+ else -> null
+ },
returnVar?.let { irReturn(declaration.symbol, irGet(it)) }
)
)
@@ -855,9 +866,15 @@
// no group, since composableLambda should already create one
// no default logic
val body = declaration.body!!
+ val sourceInformationPreamble = mutableStatementContainer()
val skipPreamble = mutableStatementContainer()
val bodyPreamble = mutableStatementContainer()
+ // First generate the source information call
+ if (collectSourceInformation && !scope.isInlinedLambda) {
+ sourceInformationPreamble.statements.add(irSourceInformation(scope))
+ }
+
// we start off assuming that we *can* skip execution of the function
var canSkipExecution = declaration.returnType.isUnit() &&
scope.allTrackedParams.none { stabilityOf(it.type).knownUnstable() }
@@ -927,6 +944,7 @@
if (collectSourceInformation && scope.isInlinedLambda)
irStartReplaceableGroup(body, scope)
else null,
+ *sourceInformationPreamble.statements.toTypedArray(),
*skipPreamble.statements.toTypedArray(),
*bodyPreamble.statements.toTypedArray(),
transformedBody,
@@ -941,6 +959,7 @@
body.startOffset,
body.endOffset,
listOfNotNull(
+ *sourceInformationPreamble.statements.toTypedArray(),
*skipPreamble.statements.toTypedArray(),
*bodyPreamble.statements.toTypedArray(),
transformed,
@@ -1740,16 +1759,61 @@
scope: Scope.BlockScope,
key: IrExpression = element.irSourceKey()
): IrExpression {
- val startDescriptor = if (scope.hasSourceInformation)
- startReplaceableSourceFunction else startReplaceableFunction
- return irMethodCall(
- irCurrentComposer(),
- startDescriptor
+ return irWithSourceInformation(
+ irMethodCall(
+ irCurrentComposer(),
+ startReplaceableFunction
+ ).also {
+ it.putValueArgument(0, key)
+ },
+ scope
+ )
+ }
+
+ private fun irWithSourceInformation(
+ startGroup: IrExpression,
+ scope: Scope.BlockScope
+ ): IrExpression {
+ return if (scope.hasSourceInformation) {
+ irBlock(statements = listOf(startGroup, irSourceInformation(scope)))
+ } else startGroup
+ }
+
+ private fun irSourceInformation(scope: Scope.BlockScope): IrExpression {
+ val sourceInformation = irCall(
+ sourceInformationFunction
).also {
- it.putValueArgument(0, key)
- if (scope.hasSourceInformation) {
- recordSourceParameter(it, 1, scope)
- }
+ it.putValueArgument(0, irCurrentComposer())
+ }
+ recordSourceParameter(sourceInformation, 1, scope)
+ return sourceInformation
+ }
+
+ private fun irSourceInformationMarkerStart(
+ element: IrElement,
+ scope: Scope.BlockScope,
+ key: IrExpression = element.irSourceKey(),
+ ): IrExpression {
+ return irCall(
+ sourceInformationMarkerStartFunction,
+ element.startOffset,
+ element.endOffset
+ ).also {
+ it.putValueArgument(0, irCurrentComposer())
+ it.putValueArgument(1, key)
+ recordSourceParameter(it, 2, scope)
+ }
+ }
+
+ private fun irSourceInformationMarkerEnd(
+ element: IrElement,
+ ): IrExpression {
+ return irCall(
+ sourceInformationMarkerEndFunction,
+ element.startOffset,
+ element.endOffset
+ ).also {
+ it.putValueArgument(0, irCurrentComposer())
}
}
@@ -1767,21 +1831,19 @@
scope: Scope.BlockScope,
key: IrExpression = element.irSourceKey()
): IrExpression {
- val startDescriptor = if (scope.hasSourceInformation)
- startRestartGroupSourceFunction else startRestartGroupFunction
- return irSet(
- nearestComposer(),
- irMethodCall(
- irCurrentComposer(),
- startDescriptor,
- element.startOffset,
- element.endOffset
- ).also {
- it.putValueArgument(0, key)
- if (scope.hasSourceInformation) {
- recordSourceParameter(it, 1, scope)
+ return irWithSourceInformation(
+ irSet(
+ nearestComposer(),
+ irMethodCall(
+ irCurrentComposer(),
+ startRestartGroupFunction,
+ element.startOffset,
+ element.endOffset
+ ).also {
+ it.putValueArgument(0, key)
}
- }
+ ),
+ scope
)
}
@@ -1854,23 +1916,18 @@
joinedData: IrExpression,
scope: Scope.BlockScope
): IrExpression {
- val startFunction = if (scope.hasSourceInformation) {
- startMovableSourceFunction
- } else {
- startMovableFunction
- }
- return irMethodCall(
- irCurrentComposer(),
- startFunction,
- element.startOffset,
- element.endOffset
- ).also {
- it.putValueArgument(0, element.irSourceKey())
- it.putValueArgument(1, joinedData)
- if (scope.hasSourceInformation) {
- recordSourceParameter(it, 2, scope)
- }
- }
+ return irWithSourceInformation(
+ irMethodCall(
+ irCurrentComposer(),
+ startMovableFunction,
+ element.startOffset,
+ element.endOffset
+ ).also {
+ it.putValueArgument(0, element.irSourceKey())
+ it.putValueArgument(1, joinedData)
+ },
+ scope
+ )
}
private fun irEndMovableGroup(): IrExpression {
@@ -2372,17 +2429,6 @@
expression
}
}
- collectSourceInformation &&
- expression.symbol.descriptor.fqNameSafe == ComposeFqNames.composableLambda -> {
- // For calls to `composableLambda` we introduce a scope to collect the source
- // locations on the top level of the lambda as the startRestartGroup is in the
- // composable lambda wrapper.
- val composableLambdaScope = withScope(Scope.ComposableLambdaScope()) {
- expression.transformChildrenVoid()
- }
- recordSourceParameter(expression, 3, composableLambdaScope)
- return expression
- }
expression.isComposableSingletonGetter() -> {
// This looks like `ComposableSingletonClass.lambda-123`, which is a static/saved
// call of composableLambdaInstance. We want to transform the property here now
@@ -2393,18 +2439,6 @@
property?.transformChildrenVoid()
return super.visitCall(expression)
}
- collectSourceInformation &&
- expression.symbol.descriptor.fqNameSafe ==
- ComposeFqNames.composableLambdaInstance -> {
- // For calls to `composableLambdaInstance` that are not singletons we introduce a
- // scope to collect the source locations on the top level of the lambda as the
- // startRestartGroup is in the composable lambda wrapper.
- val composableLambdaScope = withScope(Scope.ComposableLambdaScope()) {
- expression.transformChildrenVoid()
- }
- recordSourceParameter(expression, 2, composableLambdaScope)
- return expression
- }
else -> return super.visitCall(expression)
}
}
@@ -3329,13 +3363,9 @@
override fun calculateSourceInfo(sourceInformationEnabled: Boolean): String? =
if (sourceInformationEnabled) {
- if (function.isLambda() && !isInlinedLambda) {
- super.calculateSourceInfo(sourceInformationEnabled)
- } else {
- "${callInformation()}${parameterInformation()}${
- super.calculateSourceInfo(sourceInformationEnabled) ?: ""
- }:${sourceFileInformation()}"
- }
+ "${callInformation()}${parameterInformation()}${
+ super.calculateSourceInfo(sourceInformationEnabled) ?: ""
+ }:${sourceFileInformation()}"
} else {
if (function.visibility.isPublicAPI) {
"${callInformation()}${parameterInformation()}"
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 0bc3dcc..131e734 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
@@ -48,7 +48,6 @@
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irGetField
import org.jetbrains.kotlin.ir.builders.irInt
-import org.jetbrains.kotlin.ir.builders.irNull
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.builders.irTemporary
import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer
@@ -687,9 +686,6 @@
val shouldBeTracked = collector.captures.isNotEmpty()
putValueArgument(index++, irBuilder.irBoolean(shouldBeTracked))
- // sourceInformation parameter
- putValueArgument(index++, irBuilder.irNull())
-
// ComposableLambdaN requires the arity
if (useComposableLambdaN) {
// arity parameter
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/lazy/Lazy.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/lazy/Lazy.desktop.kt
index fbdcda7..20e25b8 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/lazy/Lazy.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/lazy/Lazy.desktop.kt
@@ -16,6 +16,10 @@
package androidx.compose.foundation.lazy
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
+import androidx.compose.ui.layout.SubcomposeLayoutState
+
internal actual fun getDefaultLazyKeyFor(index: Int): Any = DefaultLazyKey(index)
private data class DefaultLazyKey(private val index: Int)
diff --git a/compose/runtime/runtime/api/1.0.0-beta07.txt b/compose/runtime/runtime/api/1.0.0-beta07.txt
index e6427f7..6b7c331 100644
--- a/compose/runtime/runtime/api/1.0.0-beta07.txt
+++ b/compose/runtime/runtime/api/1.0.0-beta07.txt
@@ -108,14 +108,14 @@
method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+ method public void sourceInformation(String sourceInformation);
+ method public void sourceInformationMarkerEnd();
+ method public void sourceInformationMarkerStart(int key, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
- method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
@@ -139,6 +139,9 @@
public final class ComposerKt {
method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
}
public interface Composition {
@@ -498,16 +501,16 @@
}
public final class ComposableLambdaKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, String? sourceInformation, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
}
@androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
}
public final class ComposableLambdaN_jvmKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, int arity, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, String? sourceInformation, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
}
public final class DecoyKt {
diff --git a/compose/runtime/runtime/api/current.ignore b/compose/runtime/runtime/api/current.ignore
index 3676e75..87dd33f 100644
--- a/compose/runtime/runtime/api/current.ignore
+++ b/compose/runtime/runtime/api/current.ignore
@@ -5,7 +5,29 @@
Added method androidx.compose.runtime.Composer.enableReusing()
AddedAbstractMethod: androidx.compose.runtime.Composer#endReusableGroup():
Added method androidx.compose.runtime.Composer.endReusableGroup()
+AddedAbstractMethod: androidx.compose.runtime.Composer#sourceInformation(String):
+ Added method androidx.compose.runtime.Composer.sourceInformation(String)
+AddedAbstractMethod: androidx.compose.runtime.Composer#sourceInformationMarkerEnd():
+ Added method androidx.compose.runtime.Composer.sourceInformationMarkerEnd()
+AddedAbstractMethod: androidx.compose.runtime.Composer#sourceInformationMarkerStart(int, String):
+ Added method androidx.compose.runtime.Composer.sourceInformationMarkerStart(int,String)
AddedAbstractMethod: androidx.compose.runtime.Composer#startReusableGroup(int, Object):
Added method androidx.compose.runtime.Composer.startReusableGroup(int,Object)
AddedAbstractMethod: androidx.compose.runtime.Composer#startReusableNode():
Added method androidx.compose.runtime.Composer.startReusableNode()
+
+
+RemovedMethod: androidx.compose.runtime.Composer#startMovableGroup(int, Object, String):
+ Removed method androidx.compose.runtime.Composer.startMovableGroup(int,Object,String)
+RemovedMethod: androidx.compose.runtime.Composer#startReplaceableGroup(int, String):
+ Removed method androidx.compose.runtime.Composer.startReplaceableGroup(int,String)
+RemovedMethod: androidx.compose.runtime.Composer#startRestartGroup(int, String):
+ Removed method androidx.compose.runtime.Composer.startRestartGroup(int,String)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaKt#composableLambda(androidx.compose.runtime.Composer, int, boolean, String, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaKt.composableLambda(androidx.compose.runtime.Composer,int,boolean,String,Object)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaKt#composableLambdaInstance(int, boolean, String, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaKt.composableLambdaInstance(int,boolean,String,Object)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaN_jvmKt#composableLambdaN(androidx.compose.runtime.Composer, int, boolean, String, int, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaN_jvmKt.composableLambdaN(androidx.compose.runtime.Composer,int,boolean,String,int,Object)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaN_jvmKt#composableLambdaNInstance(int, boolean, String, int, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaN_jvmKt.composableLambdaNInstance(int,boolean,String,int,Object)
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index e6427f7..6b7c331 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -108,14 +108,14 @@
method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+ method public void sourceInformation(String sourceInformation);
+ method public void sourceInformationMarkerEnd();
+ method public void sourceInformationMarkerStart(int key, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
- method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
@@ -139,6 +139,9 @@
public final class ComposerKt {
method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
}
public interface Composition {
@@ -498,16 +501,16 @@
}
public final class ComposableLambdaKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, String? sourceInformation, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
}
@androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
}
public final class ComposableLambdaN_jvmKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, int arity, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, String? sourceInformation, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
}
public final class DecoyKt {
diff --git a/compose/runtime/runtime/api/public_plus_experimental_1.0.0-beta07.txt b/compose/runtime/runtime/api/public_plus_experimental_1.0.0-beta07.txt
index dc2cc91..3cbeb22 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_1.0.0-beta07.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_1.0.0-beta07.txt
@@ -114,15 +114,15 @@
method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+ method public void sourceInformation(String sourceInformation);
+ method public void sourceInformationMarkerEnd();
+ method public void sourceInformationMarkerStart(int key, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
- method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
method @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<?>![] values);
method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
@@ -146,6 +146,9 @@
public final class ComposerKt {
method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
}
public interface Composition {
@@ -516,16 +519,16 @@
}
public final class ComposableLambdaKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, String? sourceInformation, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
}
@androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
}
public final class ComposableLambdaN_jvmKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, int arity, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, String? sourceInformation, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
}
@androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface Decoy {
diff --git a/compose/runtime/runtime/api/public_plus_experimental_current.txt b/compose/runtime/runtime/api/public_plus_experimental_current.txt
index dc2cc91..3cbeb22 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_current.txt
@@ -114,15 +114,15 @@
method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+ method public void sourceInformation(String sourceInformation);
+ method public void sourceInformationMarkerEnd();
+ method public void sourceInformationMarkerStart(int key, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
- method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
method @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<?>![] values);
method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
@@ -146,6 +146,9 @@
public final class ComposerKt {
method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
}
public interface Composition {
@@ -516,16 +519,16 @@
}
public final class ComposableLambdaKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, String? sourceInformation, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
}
@androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
}
public final class ComposableLambdaN_jvmKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, int arity, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, String? sourceInformation, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
}
@androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget, kotlin.annotation.AnnotationTarget}) public @interface Decoy {
diff --git a/compose/runtime/runtime/api/restricted_1.0.0-beta07.txt b/compose/runtime/runtime/api/restricted_1.0.0-beta07.txt
index 5dbea01..2cd34c5 100644
--- a/compose/runtime/runtime/api/restricted_1.0.0-beta07.txt
+++ b/compose/runtime/runtime/api/restricted_1.0.0-beta07.txt
@@ -110,14 +110,14 @@
method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+ method public void sourceInformation(String sourceInformation);
+ method public void sourceInformationMarkerEnd();
+ method public void sourceInformationMarkerStart(int key, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
- method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
@@ -141,6 +141,9 @@
public final class ComposerKt {
method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
field @kotlin.PublishedApi internal static final Object compositionLocalMap;
field @kotlin.PublishedApi internal static final int compositionLocalMapKey = 202; // 0xca
field @kotlin.PublishedApi internal static final Object invocation;
@@ -526,16 +529,16 @@
}
public final class ComposableLambdaKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, String? sourceInformation, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
}
@androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
}
public final class ComposableLambdaN_jvmKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, int arity, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, String? sourceInformation, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
}
public final class DecoyKt {
diff --git a/compose/runtime/runtime/api/restricted_current.ignore b/compose/runtime/runtime/api/restricted_current.ignore
index 3676e75..87dd33f 100644
--- a/compose/runtime/runtime/api/restricted_current.ignore
+++ b/compose/runtime/runtime/api/restricted_current.ignore
@@ -5,7 +5,29 @@
Added method androidx.compose.runtime.Composer.enableReusing()
AddedAbstractMethod: androidx.compose.runtime.Composer#endReusableGroup():
Added method androidx.compose.runtime.Composer.endReusableGroup()
+AddedAbstractMethod: androidx.compose.runtime.Composer#sourceInformation(String):
+ Added method androidx.compose.runtime.Composer.sourceInformation(String)
+AddedAbstractMethod: androidx.compose.runtime.Composer#sourceInformationMarkerEnd():
+ Added method androidx.compose.runtime.Composer.sourceInformationMarkerEnd()
+AddedAbstractMethod: androidx.compose.runtime.Composer#sourceInformationMarkerStart(int, String):
+ Added method androidx.compose.runtime.Composer.sourceInformationMarkerStart(int,String)
AddedAbstractMethod: androidx.compose.runtime.Composer#startReusableGroup(int, Object):
Added method androidx.compose.runtime.Composer.startReusableGroup(int,Object)
AddedAbstractMethod: androidx.compose.runtime.Composer#startReusableNode():
Added method androidx.compose.runtime.Composer.startReusableNode()
+
+
+RemovedMethod: androidx.compose.runtime.Composer#startMovableGroup(int, Object, String):
+ Removed method androidx.compose.runtime.Composer.startMovableGroup(int,Object,String)
+RemovedMethod: androidx.compose.runtime.Composer#startReplaceableGroup(int, String):
+ Removed method androidx.compose.runtime.Composer.startReplaceableGroup(int,String)
+RemovedMethod: androidx.compose.runtime.Composer#startRestartGroup(int, String):
+ Removed method androidx.compose.runtime.Composer.startRestartGroup(int,String)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaKt#composableLambda(androidx.compose.runtime.Composer, int, boolean, String, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaKt.composableLambda(androidx.compose.runtime.Composer,int,boolean,String,Object)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaKt#composableLambdaInstance(int, boolean, String, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaKt.composableLambdaInstance(int,boolean,String,Object)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaN_jvmKt#composableLambdaN(androidx.compose.runtime.Composer, int, boolean, String, int, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaN_jvmKt.composableLambdaN(androidx.compose.runtime.Composer,int,boolean,String,int,Object)
+RemovedMethod: androidx.compose.runtime.internal.ComposableLambdaN_jvmKt#composableLambdaNInstance(int, boolean, String, int, Object):
+ Removed method androidx.compose.runtime.internal.ComposableLambdaN_jvmKt.composableLambdaNInstance(int,boolean,String,int,Object)
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index 5dbea01..2cd34c5 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -110,14 +110,14 @@
method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+ method public void sourceInformation(String sourceInformation);
+ method public void sourceInformationMarkerEnd();
+ method public void sourceInformationMarkerStart(int key, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
- method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
- method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key, String? sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
@@ -141,6 +141,9 @@
public final class ComposerKt {
method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+ method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
field @kotlin.PublishedApi internal static final Object compositionLocalMap;
field @kotlin.PublishedApi internal static final int compositionLocalMapKey = 202; // 0xca
field @kotlin.PublishedApi internal static final Object invocation;
@@ -526,16 +529,16 @@
}
public final class ComposableLambdaKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, String? sourceInformation, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
}
@androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
}
public final class ComposableLambdaN_jvmKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, String? sourceInformation, int arity, Object block);
- method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, String? sourceInformation, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
}
public final class DecoyKt {
diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle
index f6127c3..d8bae21 100644
--- a/compose/runtime/runtime/build.gradle
+++ b/compose/runtime/runtime/build.gradle
@@ -106,6 +106,9 @@
}
android {
+ defaultConfig {
+ consumerProguardFiles 'proguard-rules.pro'
+ }
buildTypes {
debug {
testCoverageEnabled = false
diff --git a/compose/runtime/runtime/proguard-rules.pro b/compose/runtime/runtime/proguard-rules.pro
new file mode 100644
index 0000000..0343d92
--- /dev/null
+++ b/compose/runtime/runtime/proguard-rules.pro
@@ -0,0 +1,5 @@
+-assumenosideeffects public class androidx.compose.runtime.ComposerKt {
+ void sourceInformation(androidx.compose.runtime.Composer,java.lang.String);
+ void sourceInformationMarkerStart(androidx.compose.runtime.Composer,int,java.lang.String);
+ void sourceInformationMarkerEnd(androidx.compose.runtime.Composer);
+}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
index 2f86602..3f84fc1 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
@@ -378,7 +378,7 @@
* execution and can only either inserted, removed, or replaced. For example, the group
* created by most control flow constructs such as an `if` statement are replacable groups.
*
- * @param key An compiler generated key based on the source location of the call.
+ * @param key A compiler generated key based on the source location of the call.
*/
@ComposeCompilerApi
fun startReplaceableGroup(key: Int)
@@ -386,20 +386,6 @@
/**
* A Compose compiler plugin API. DO NOT call directly.
*
- * Start a replacable group. A replacable group is a group that cannot be moved during
- * execution and can only either inserted, removed, or replaced. For example, the group
- * created by most control flow constructs such as an `if` statement are replacable groups.
- *
- * @param key An compiler generated key based on the source location of the call.
- * @param sourceInformation An optional string value to that provides the compose tools enough
- * information to calculate the source location calls made in the group.
- */
- @ComposeCompilerApi
- fun startReplaceableGroup(key: Int, sourceInformation: String?)
-
- /**
- * A Compose compiler plugin API. DO NOT call directly.
- *
* Called at the end of a replacable group.
*
* @see startRestartGroup
@@ -418,7 +404,7 @@
* the state and nodes generated by a loop to move with the composition implied by the key
* passed to [key][androidx.compose.runtime.key].
- * @param key An compiler generated key based on the source location of the call.
+ * @param key A compiler generated key based on the source location of the call.
*/
@ComposeCompilerApi
fun startMovableGroup(key: Int, dataKey: Any?)
@@ -426,24 +412,6 @@
/**
* A Compose compiler plugin API. DO NOT call directly.
*
- * Start a movable group. A movable group is one that can be moved based on the value of
- * [dataKey] which is typically supplied by the [key][androidx.compose.runtime.key] pseudo
- * compiler function.
- *
- * A movable group implements the semantics of [key][androidx.compose.runtime.key] which allows
- * the state and nodes generated by a loop to move with the composition implied by the key
- * passed to [key][androidx.compose.runtime.key].
-
- * @param key An compiler generated key based on the source location of the call.
- * @param sourceInformation An optional string value to that provides the compose tools enough
- * information to calculate the source location calls made in the group.
- */
- @ComposeCompilerApi
- fun startMovableGroup(key: Int, dataKey: Any?, sourceInformation: String?)
-
- /**
- * A Compose compiler plugin API. DO NOT call directly.
- *
* Called at the end of a movable group.
*
* @see startMovableGroup
@@ -481,7 +449,7 @@
* recomposed on demand based on the lambda passed to
* [updateScope][ScopeUpdateScope.updateScope] when [endRestartGroup] is called
*
- * @param key An compiler generated key based on the source location of the call.
+ * @param key A compiler generated key based on the source location of the call.
* @return the instance of the composer to use for the rest of the function.
*/
@ComposeCompilerApi
@@ -490,21 +458,6 @@
/**
* A Compose compiler plugin API. DO NOT call directly.
*
- * Called to record a group for a [Composable] function and starts a group that can be
- * recomposed on demand based on the lambda passed to
- * [updateScope][ScopeUpdateScope.updateScope] when [endRestartGroup] is called
- *
- * @param key An compiler generated key based on the source location of the call.
- * @param sourceInformation An optional string value to that provides the compose tools enough
- * information to calculate the source location calls made in the group.
- * @return the instance of the composer to use for the rest of the function.
- */
- @ComposeCompilerApi
- fun startRestartGroup(key: Int, sourceInformation: String?): Composer
-
- /**
- * A Compose compiler plugin API. DO NOT call directly.
- *
* Called to end a restart group.
*/
@ComposeCompilerApi
@@ -513,6 +466,38 @@
/**
* A Compose compiler plugin API. DO NOT call directly.
*
+ * Record the source information string for a group. This must be immediately called after the
+ * start of a group.
+ *
+ * @param sourceInformation An string value to that provides the compose tools enough
+ * information to calculate the source location of calls to composable functions.
+ */
+ fun sourceInformation(sourceInformation: String)
+
+ /**
+ * A compose compiler plugin API. DO NOT call directly.
+ *
+ * Record a source information marker. This marker can be used in place of a group that would
+ * have contained the information but was elided as the compiler plugin determined the group
+ * was not necessary such as when a function is marked with [ReadOnlyComposable].
+ *
+ * @param key A compiler generated key based on the source location of the call.
+ * @param sourceInformation An string value to that provides the compose tools enough
+ * information to calculate the source location of calls to composable functions.
+ *
+ */
+ fun sourceInformationMarkerStart(key: Int, sourceInformation: String)
+
+ /**
+ * A compose compiler plugin API. DO NOT call directly.
+ *
+ * Record the end of the marked source information range.
+ */
+ fun sourceInformationMarkerEnd()
+
+ /**
+ * A Compose compiler plugin API. DO NOT call directly.
+ *
* Skips the composer to the end of the current group. This generated by the compiler to when
* the body of a [Composable] function can be skipped typically because the parameters to the
* function are equal to the values passed to it in the previous composition.
@@ -959,6 +944,52 @@
}
/**
+ * A Compose internal function. DO NOT call directly.
+ *
+ * Records source information that can be used for tooling to determine the source location of
+ * the corresponding composable function. By default, this function is declared as having no
+ * side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove it.
+ */
+@ComposeCompilerApi
+fun sourceInformation(composer: Composer, sourceInformation: String) {
+ composer.sourceInformation(sourceInformation)
+}
+
+/**
+ * A Compose internal function. DO NOT call directly.
+ *
+ * Records the start of a source information marker that can be used for tooling to determine the
+ * source location of the corresponding composable function that otherwise don't require tracking
+ * information such as [ReadOnlyComposable] functions. By default, this function is declared as
+ * having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove
+ * it.
+ *
+ * Important that both [sourceInformationMarkerStart] and [sourceInformationMarkerEnd] are removed
+ * together or both kept. Removing only one will cause incorrect runtime behavior.
+ */
+@ComposeCompilerApi
+fun sourceInformationMarkerStart(composer: Composer, key: Int, sourceInformation: String) {
+ composer.sourceInformationMarkerStart(key, sourceInformation)
+}
+
+/**
+ * A Compose internal function. DO NOT call directly.
+ *
+ * Records the end of a source information marker that can be used for tooling to determine the
+ * source location of the corresponding composable function that otherwise don't require tracking
+ * information such as [ReadOnlyComposable] functions. By default, this function is declared as
+ * having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove
+ * it.
+ *
+ * Important that both [sourceInformationMarkerStart] and [sourceInformationMarkerEnd] are removed
+ * together or both kept. Removing only one will cause incorrect runtime behavior.
+ */
+@ComposeCompilerApi
+fun sourceInformationMarkerEnd(composer: Composer) {
+ composer.sourceInformationMarkerEnd()
+}
+
+/**
* Implementation of a composer for a mutable tree.
*/
internal class ComposerImpl(
@@ -1053,10 +1084,6 @@
@ComposeCompilerApi
override fun startReplaceableGroup(key: Int) = start(key, null, false, null)
- @ComposeCompilerApi
- override fun startReplaceableGroup(key: Int, sourceInformation: String?) =
- start(key, null, false, sourceInformation)
-
/**
* Indicates the end of a "Replaceable Group" at the current execution position. A
* Replaceable Group is a group which cannot be moved between its siblings, but
@@ -1136,10 +1163,6 @@
@ComposeCompilerApi
override fun startMovableGroup(key: Int, dataKey: Any?) = start(key, dataKey, false, null)
- @ComposeCompilerApi
- override fun startMovableGroup(key: Int, dataKey: Any?, sourceInformation: String?) =
- start(key, dataKey, false, sourceInformation)
-
/**
* Indicates the end of a "Movable Group" at the current execution position. A Movable Group is
* a group which can be moved or reordered between its siblings and retain slot table state,
@@ -2414,13 +2437,6 @@
return this
}
- @ComposeCompilerApi
- override fun startRestartGroup(key: Int, sourceInformation: String?): Composer {
- start(key, null, false, sourceInformation)
- addRecomposeScope()
- return this
- }
-
private fun addRecomposeScope() {
if (inserting) {
val scope = RecomposeScopeImpl(composition as CompositionImpl)
@@ -2469,6 +2485,23 @@
return result
}
+ @ComposeCompilerApi
+ override fun sourceInformation(sourceInformation: String) {
+ if (inserting) {
+ writer.insertAux(sourceInformation)
+ }
+ }
+
+ @ComposeCompilerApi
+ override fun sourceInformationMarkerStart(key: Int, sourceInformation: String) {
+ start(key, objectKey = null, isNode = false, data = sourceInformation)
+ }
+
+ @ComposeCompilerApi
+ override fun sourceInformationMarkerEnd() {
+ end(isNode = false)
+ }
+
/**
* Synchronously compose the initial composition of [content]. This collects all the changes
* which must be applied by [ControlledComposition.applyChanges] to build the tree implied by
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 8b84b4a..8e8a725 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
@@ -1127,6 +1127,37 @@
}
/**
+ * Insert aux data into the parent group.
+ *
+ * This must be done only after at most one value has been inserted into the slot table for
+ * the group.
+ */
+ fun insertAux(value: Any?) {
+ check(insertCount >= 0) { "Cannot insert auxiliary data when not inserting" }
+ val parent = parent
+ val parentGroupAddress = groupIndexToAddress(parent)
+ check(!groups.hasAux(parentGroupAddress)) { "Group already has auxiliary data" }
+ insertSlots(1, parent)
+ val auxIndex = groups.auxIndex(parentGroupAddress)
+ val auxAddress = dataIndexToDataAddress(auxIndex)
+ if (currentSlot > auxIndex) {
+ // One or more values were inserted into the slot table before the aux value, we need
+ // to move them. Currently we only will run into one or two slots (the recompose
+ // scope inserted by a restart group and the lambda value in a composableLambda
+ // instance) so this is the only case currently supported.
+ val slotsToMove = currentSlot - auxIndex
+ check(slotsToMove < 3) { "Moving more than two slot not supported" }
+ if (slotsToMove > 1) {
+ slots[auxAddress + 2] = slots[auxAddress + 1]
+ }
+ slots[auxAddress + 1] = slots[auxAddress]
+ }
+ groups.addAux(parentGroupAddress)
+ slots[auxAddress] = value
+ currentSlot++
+ }
+
+ /**
* Updates the node for the current node group to [value].
*/
fun updateNode(value: Any?) = updateNodeOfGroup(currentGroup, value)
@@ -2463,7 +2494,7 @@
// 31 30 29 28_27 26 25 24_23 22 21 20_19 18 17 16__15 14 13 12_11 10 09 08_07 06 05 04_03 02 01 00
// 0 n ks ds r | node count |
// where n is set when the group represents a node
-// where ks is whether the group has a data key slot
+// where ks is whether the group has a object key slot
// where ds is whether the group has a group data slot
// where r is always 0 (future use)
@@ -2508,6 +2539,11 @@
}
private fun IntArray.hasAux(address: Int) =
this[address * Group_Fields_Size + GroupInfo_Offset] and Aux_Mask != 0
+private fun IntArray.addAux(address: Int) {
+ val arrayIndex = address * Group_Fields_Size + GroupInfo_Offset
+ this[arrayIndex] = this[arrayIndex] or Aux_Mask
+}
+
private fun IntArray.auxIndex(address: Int) = (address * Group_Fields_Size).let { slot ->
if (slot >= size) size
else this[slot + DataAnchor_Offset] +
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.kt
index f2cdb63..368da08 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.kt
@@ -47,8 +47,7 @@
/* ktlint-disable parameter-list-wrapping */ // TODO(https://github.com/pinterest/ktlint/issues/921): reenable
internal expect class ComposableLambdaImpl(
key: Int,
- tracked: Boolean,
- sourceInformation: String?
+ tracked: Boolean
) : ComposableLambda {
fun update(block: Any)
}
@@ -327,13 +326,12 @@
composer: Composer,
key: Int,
tracked: Boolean,
- sourceInformation: String?,
block: Any
): ComposableLambda {
composer.startReplaceableGroup(key)
val slot = composer.rememberedValue()
val result = if (slot === Composer.Empty) {
- val value = ComposableLambdaImpl(key, tracked, sourceInformation)
+ val value = ComposableLambdaImpl(key, tracked)
composer.updateRememberedValue(value)
value
} else {
@@ -349,7 +347,6 @@
fun composableLambdaInstance(
key: Int,
tracked: Boolean,
- sourceInformation: String?,
block: Any
): ComposableLambda =
- ComposableLambdaImpl(key, tracked, sourceInformation).apply { update(block) }
+ ComposableLambdaImpl(key, tracked).apply { update(block) }
diff --git a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.jvm.kt b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.jvm.kt
index 572c146..172a413 100644
--- a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.jvm.kt
+++ b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambda.jvm.kt
@@ -36,8 +36,7 @@
/* ktlint-disable parameter-list-wrapping */ // TODO(https://github.com/pinterest/ktlint/issues/921): reenable
internal actual class ComposableLambdaImpl actual constructor(
val key: Int,
- private val tracked: Boolean,
- private val sourceInformation: String?
+ private val tracked: Boolean
) : ComposableLambda {
private var _block: Any? = null
private var scope: RecomposeScope? = null
@@ -102,7 +101,7 @@
}
override operator fun invoke(c: Composer, changed: Int): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(0) else sameBits(0)
val result = (_block as (c: Composer, changed: Int) -> Any?)(c, dirty)
@@ -111,7 +110,7 @@
}
override operator fun invoke(p1: Any?, c: Composer, changed: Int): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(1) else sameBits(1)
val result = (
@@ -130,7 +129,7 @@
}
override operator fun invoke(p1: Any?, p2: Any?, c: Composer, changed: Int): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(2) else sameBits(2)
val result = (_block as (p1: Any?, p2: Any?, c: Composer, changed: Int) -> Any?)(
@@ -144,7 +143,7 @@
}
override operator fun invoke(p1: Any?, p2: Any?, p3: Any?, c: Composer, changed: Int): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(3) else sameBits(3)
val result = (
@@ -174,7 +173,7 @@
c: Composer,
changed: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(4) else sameBits(4)
val result = (
@@ -209,7 +208,7 @@
c: Composer,
changed: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(5) else sameBits(5)
val result = (
@@ -247,7 +246,7 @@
c: Composer,
changed: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(6) else sameBits(6)
val result = (
@@ -288,7 +287,7 @@
c: Composer,
changed: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(7) else sameBits(7)
val result = (
@@ -332,7 +331,7 @@
c: Composer,
changed: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(8) else sameBits(8)
val result = (
@@ -379,7 +378,7 @@
c: Composer,
changed: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed or if (c.changed(this)) differentBits(9) else sameBits(9)
val result = (
@@ -430,7 +429,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(10) else sameBits(10)
val result = (
@@ -486,7 +485,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(11) else sameBits(11)
val result = (
@@ -545,7 +544,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(12) else sameBits(12)
val result = (
@@ -607,7 +606,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(13) else sameBits(13)
val result = (
@@ -689,7 +688,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(14) else sameBits(14)
val result = (
@@ -775,7 +774,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(15) else sameBits(15)
val result = (
@@ -865,7 +864,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(16) else sameBits(16)
val result = (
@@ -959,7 +958,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(17) else sameBits(17)
val result = (
@@ -1057,7 +1056,7 @@
changed: Int,
changed1: Int
): Any? {
- val c = c.startRestartGroup(key, sourceInformation)
+ val c = c.startRestartGroup(key)
trackRead(c)
val dirty = changed1 or if (c.changed(this)) differentBits(18) else sameBits(18)
val result = (
diff --git a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambdaN.jvm.kt b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambdaN.jvm.kt
index 08e88f1..3193f395 100644
--- a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambdaN.jvm.kt
+++ b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/internal/ComposableLambdaN.jvm.kt
@@ -30,7 +30,6 @@
internal class ComposableLambdaNImpl(
val key: Int,
private val tracked: Boolean,
- private val sourceInformation: String?,
override val arity: Int
) : ComposableLambdaN {
private var _block: Any? = null
@@ -112,7 +111,7 @@
var c = args[realParams] as Composer
val allArgsButLast = args.slice(0 until args.size - 1).toTypedArray()
val lastChanged = args[args.size - 1] as Int
- c = c.startRestartGroup(key, sourceInformation)
+ c = c.startRestartGroup(key)
trackRead(c)
val dirty = lastChanged or if (c.changed(this))
differentBits(realParams)
@@ -146,14 +145,13 @@
composer: Composer,
key: Int,
tracked: Boolean,
- sourceInformation: String?,
arity: Int,
block: Any
): ComposableLambdaN {
composer.startReplaceableGroup(key)
val slot = composer.rememberedValue()
val result = if (slot === Composer.Empty) {
- val value = ComposableLambdaNImpl(key, tracked, sourceInformation, arity)
+ val value = ComposableLambdaNImpl(key, tracked, arity)
composer.updateRememberedValue(value)
value
} else {
@@ -170,12 +168,10 @@
fun composableLambdaNInstance(
key: Int,
tracked: Boolean,
- sourceInformation: String?,
arity: Int,
block: Any
): ComposableLambdaN = ComposableLambdaNImpl(
key,
tracked,
- sourceInformation,
arity
).apply { update(block) }
diff --git a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/SlotTableTests.kt b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/SlotTableTests.kt
index 90d50e4..f5498d2 100644
--- a/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/SlotTableTests.kt
+++ b/compose/runtime/runtime/src/test/kotlin/androidx/compose/runtime/SlotTableTests.kt
@@ -3139,6 +3139,95 @@
}
slots.verifyWellFormed()
}
+
+ @Test
+ fun canInsertAuxData() {
+ val slots = SlotTable().also {
+ it.write { writer ->
+ writer.insert {
+ // Insert a normal aux data.
+ writer.startData(10, 10, "10")
+ writer.endGroup()
+
+ // Insert using insertAux
+ writer.startGroup(20)
+ writer.insertAux("20")
+ writer.endGroup()
+
+ // Insert using insertAux after a slot value was added.
+ writer.startGroup(30)
+ writer.update(300)
+ writer.insertAux("30")
+ writer.endGroup()
+
+ // Insert using insertAux after a group with an object key
+ writer.startGroup(40, 40)
+ writer.insertAux("40")
+ writer.endGroup()
+
+ // Insert aux into an object key with a value slot and then add another value.
+ writer.startGroup(50, 50)
+ writer.update(500)
+ writer.insertAux("50")
+ writer.update(501)
+ writer.endGroup()
+
+ // Insert aux after two slot values and then add another value.
+ writer.startGroup(60)
+ writer.update(600)
+ writer.update(601)
+ writer.insertAux("60")
+ writer.update(602)
+ writer.endGroup()
+
+ // Write a trail group to ensure that the slot table is valid after the
+ // insertAux
+ writer.startGroup(1000)
+ writer.update(10000)
+ writer.update(10001)
+ writer.endGroup()
+ }
+ }
+ }
+ slots.verifyWellFormed()
+ slots.read { reader ->
+ assertEquals(10, reader.groupKey)
+ assertEquals(10, reader.groupObjectKey)
+ assertEquals("10", reader.groupAux)
+ reader.skipGroup()
+ assertEquals(20, reader.groupKey)
+ assertEquals("20", reader.groupAux)
+ reader.skipGroup()
+ assertEquals(30, reader.groupKey)
+ assertEquals("30", reader.groupAux)
+ reader.startGroup()
+ assertEquals(300, reader.next())
+ reader.endGroup()
+ assertEquals(40, reader.groupKey)
+ assertEquals(40, reader.groupObjectKey)
+ assertEquals("40", reader.groupAux)
+ reader.skipGroup()
+ assertEquals(50, reader.groupKey)
+ assertEquals(50, reader.groupObjectKey)
+ assertEquals("50", reader.groupAux)
+ reader.startGroup()
+ assertEquals(500, reader.next())
+ assertEquals(501, reader.next())
+ reader.endGroup()
+ assertEquals(60, reader.groupKey)
+ assertEquals("60", reader.groupAux)
+ reader.startGroup()
+ assertEquals(600, reader.next())
+ assertEquals(601, reader.next())
+ assertEquals(602, reader.next())
+ reader.endGroup()
+ assertEquals(1000, reader.groupKey)
+ reader.startGroup()
+ assertEquals(10000, reader.next())
+ assertEquals(10001, reader.next())
+ reader.endGroup()
+ }
+ }
}
@OptIn(InternalComposeApi::class)
diff --git a/compose/ui/ui-test-junit4/build.gradle b/compose/ui/ui-test-junit4/build.gradle
index 1923226..9a89811 100644
--- a/compose/ui/ui-test-junit4/build.gradle
+++ b/compose/ui/ui-test-junit4/build.gradle
@@ -85,6 +85,7 @@
implementation("androidx.annotation:annotation:1.1.0")
implementation(KOTLIN_COROUTINES_CORE)
+ implementation(KOTLIN_COROUTINES_TEST)
}
androidMain.dependencies {
@@ -99,7 +100,6 @@
implementation(ANDROIDX_TEST_MONITOR)
implementation(ESPRESSO_CORE)
implementation(ESPRESSO_IDLING_RESOURCE)
- implementation(KOTLIN_COROUTINES_TEST)
}
androidAndroidTest.dependencies {
diff --git a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt
index 0c5823c..01d4151 100644
--- a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt
+++ b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionsInCoroutinesTest.kt
@@ -23,10 +23,7 @@
import androidx.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
-import org.junit.rules.RuleChain
-import org.junit.rules.TestRule
import org.junit.runner.RunWith
-import org.junit.runners.model.Statement
@LargeTest
@RunWith(AndroidJUnit4::class)
@@ -34,23 +31,8 @@
private class TestException : Exception()
- // Need to expect the error in a test rule around the AndroidComposeTestRule, because the
- // exception can surface after the test is completed, when the AndroidComposeTestRule cleans
- // up test scoped variables.
- private val testExceptionRule = TestRule { base, _ ->
- object : Statement() {
- override fun evaluate() {
- expectError<TestException> {
- base.evaluate()
- }
- }
- }
- }
-
- private val rule = createComposeRule()
-
@get:Rule
- val testRule: TestRule = RuleChain.outerRule(testExceptionRule).around(rule)
+ val rule = createComposeRule()
// Run the test twice so we can verify if a failed test took down the test suite:
// - Results have 1 failed test:
@@ -60,12 +42,16 @@
@Test
fun test1() {
- throwInLaunchedEffect()
+ expectError<TestException> {
+ throwInLaunchedEffect()
+ }
}
@Test
fun test2() {
- throwInLaunchedEffect()
+ expectError<TestException> {
+ throwInLaunchedEffect()
+ }
}
private fun throwInLaunchedEffect() {
diff --git a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt
index 75569f83..b5f158a 100644
--- a/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt
+++ b/compose/ui/ui-test-junit4/src/androidMain/kotlin/androidx/compose/ui/test/junit4/AndroidComposeTestRule.android.kt
@@ -61,7 +61,6 @@
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestCoroutineDispatcher
-import kotlinx.coroutines.test.TestCoroutineExceptionHandler
import kotlinx.coroutines.withContext
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
@@ -185,8 +184,7 @@
private val testCoroutineDispatcher: TestCoroutineDispatcher
private val recomposerApplyCoroutineScope: CoroutineScope
private val frameCoroutineScope: CoroutineScope
- @OptIn(ExperimentalCoroutinesApi::class)
- private val coroutineExceptionHandler: TestCoroutineExceptionHandler
+ private val coroutineExceptionHandler = UncaughtExceptionHandler()
override val mainClock: MainTestClock
get() = mainClockImpl
@@ -207,8 +205,6 @@
}
}
@OptIn(ExperimentalCoroutinesApi::class)
- coroutineExceptionHandler = TestCoroutineExceptionHandler()
- @OptIn(ExperimentalCoroutinesApi::class)
recomposerApplyCoroutineScope = CoroutineScope(
testCoroutineDispatcher + frameClock + infiniteAnimationPolicy +
coroutineExceptionHandler + Job()
@@ -287,7 +283,7 @@
// Then await composition(s)
runEspressoOnIdle()
}
- checkUncaughtCoroutineExceptions()
+ coroutineExceptionHandler.throwUncaught()
}
override fun <T> runOnUiThread(action: () -> T): T {
@@ -326,18 +322,6 @@
idlingResourceRegistry.unregisterIdlingResource(idlingResource)
}
- /**
- * Checks if the [coroutineExceptionHandler] has caught uncaught exceptions. If so, will
- * rethrow the first to fail the test. Rather than only calling this only at the end of the
- * test, as recommended by [cleanupTestCoroutines][kotlinx.coroutines.test
- * .UncaughtExceptionCaptor.cleanupTestCoroutines], try calling this at a few strategic
- * points to fail the test asap after the exception was caught.
- */
- private fun checkUncaughtCoroutineExceptions() {
- @OptIn(ExperimentalCoroutinesApi::class)
- coroutineExceptionHandler.cleanupTestCoroutines()
- }
-
inner class AndroidComposeStatement(
private val base: Statement
) : Statement() {
@@ -363,7 +347,7 @@
// throwing errors on active coroutines
recomposerApplyCoroutineScope.cancel()
frameCoroutineScope.cancel()
- checkUncaughtCoroutineExceptions()
+ coroutineExceptionHandler.throwUncaught()
@OptIn(ExperimentalCoroutinesApi::class)
testCoroutineDispatcher.cleanupTestCoroutines()
textInputServiceFactory = oldTextInputFactory
@@ -456,7 +440,7 @@
// between now and when the new Activity has created its compose root, even though
// waitForComposeRoots() suggests that we are now guaranteed one.
- checkUncaughtCoroutineExceptions()
+ coroutineExceptionHandler.throwUncaught()
}
override fun getRoots(atLeastOneRootExpected: Boolean): Set<RootForTest> {
diff --git a/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/DesktopComposeTestRule.desktop.kt b/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/DesktopComposeTestRule.desktop.kt
index 7038f13..e055101 100644
--- a/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/DesktopComposeTestRule.desktop.kt
+++ b/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/DesktopComposeTestRule.desktop.kt
@@ -49,10 +49,6 @@
@OptIn(InternalTestApi::class)
class DesktopComposeTestRule : ComposeContentTestRule {
- companion object {
- var current: DesktopComposeTestRule? = null
- }
-
override val density: Density
get() = Density(1f, 1f)
@@ -61,13 +57,13 @@
internal val testDisplaySize: IntSize get() = IntSize(1024, 768)
+ private var uncaughtExceptionHandler = UncaughtExceptionHandler()
lateinit var window: TestComposeWindow
private val testOwner = DesktopTestOwner(this)
private val testContext = createTestContext(testOwner)
override fun apply(base: Statement, description: Description?): Statement {
- current = this
return object : Statement() {
override fun evaluate() {
window = runOnUiThread(::createWindow)
@@ -77,6 +73,8 @@
} finally {
runOnUiThread(window::dispose)
}
+
+ uncaughtExceptionHandler.throwUncaught()
}
}
}
@@ -86,7 +84,7 @@
height = testDisplaySize.height,
density = density,
nanoTime = System::nanoTime, // TODO(demin): use mainClock?
- coroutineContext = Dispatchers.Swing
+ coroutineContext = Dispatchers.Swing + uncaughtExceptionHandler
)
private fun isIdle() =
@@ -96,6 +94,7 @@
override fun waitForIdle() {
while (!isIdle()) {
Thread.sleep(10)
+ uncaughtExceptionHandler.throwUncaught()
}
}
@@ -103,6 +102,7 @@
override suspend fun awaitIdle() {
while (!isIdle()) {
delay(10)
+ uncaughtExceptionHandler.throwUncaught()
}
}
diff --git a/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt b/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt
new file mode 100644
index 0000000..b25d2ba
--- /dev/null
+++ b/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.test.junit4
+
+import kotlinx.coroutines.CoroutineExceptionHandler
+import kotlin.coroutines.AbstractCoroutineContextElement
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Similar to [TestCoroutineExceptionHandler], but with clearing all thrown exceptions
+ *
+ * If we don't clear exceptions they will be thrown twice in this example
+ * (the exception will be thrown inside awaitIdle and after the test):
+ * ```
+ * @Test
+ * fun test() {
+ * runBlocking(Dispatchers.Main) {
+ * try {
+ * rule.awaitIdle()
+ * } catch (e: SomeException) {
+ * // ignore
+ * }
+ * }
+ * }
+ * ```
+ */
+internal class UncaughtExceptionHandler :
+ AbstractCoroutineContextElement(CoroutineExceptionHandler),
+ CoroutineExceptionHandler {
+ private var exception: Throwable? = null
+
+ override fun handleException(context: CoroutineContext, exception: Throwable) {
+ synchronized(this) {
+ if (this.exception == null) {
+ this.exception = exception
+ } else {
+ this.exception!!.addSuppressed(exception)
+ }
+ }
+ }
+
+ /**
+ * Checks if the [UncaughtExceptionHandler] has caught uncaught exceptions. If so, will
+ * rethrow the first to fail the test. The rest exceptions will be added to the first and
+ * marked as `suppressed`.
+ *
+ * The next call of this method will not throw already thrown exception.
+ *
+ * Rather than only calling this only at the end of the test, as recommended by
+ * [UncaughtExceptionCaptor.cleanupTestCoroutines],
+ * try calling this at a few strategic
+ * points to fail the test asap after the exception was caught.
+ */
+ fun throwUncaught() {
+ synchronized(this) {
+ val exception = exception
+ if (exception != null) {
+ this.exception = null
+ throw exception
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt
index 6586019..7a27e67 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/DesktopOwners.desktop.kt
@@ -73,7 +73,7 @@
private val dispatcher = FlushCoroutineDispatcher(coroutineScope)
private val frameClock = BroadcastFrameClock(onNewAwaiters = ::invalidateIfNeeded)
- private val coroutineContext = dispatcher + frameClock
+ private val coroutineContext = coroutineScope.coroutineContext + dispatcher + frameClock
internal val recomposer = Recomposer(coroutineContext)
internal val platformInputService: DesktopPlatformInput = DesktopPlatformInput(component)
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
index 15d19ba..cddba9b 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
@@ -25,6 +25,7 @@
import androidx.compose.ui.unit.Density
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.cancel
import org.jetbrains.skija.Surface
@@ -59,7 +60,7 @@
private val canvas = surface.canvas
private var owner: DesktopOwner? = null
- private val coroutineScope = CoroutineScope(coroutineContext)
+ private val coroutineScope = CoroutineScope(coroutineContext + Job())
private val frameDispatcher: FrameDispatcher = FrameDispatcher(
onFrame = { onFrame() },
context = coroutineScope.coroutineContext
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt
index d3345e2..b6073f5 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopOwnerTest.kt
@@ -46,8 +46,11 @@
import androidx.compose.ui.input.mouse.MouseScrollUnit
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.test.junit4.DesktopScreenshotTestRule
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertFalse
import org.junit.Rule
import org.junit.Test
@@ -55,6 +58,8 @@
class DesktopOwnerTest {
@get:Rule
val screenshotRule = DesktopScreenshotTestRule("ui/ui-desktop/ui")
+ @get:Rule
+ val composeRule = createComposeRule()
@Test(timeout = 5000)
fun `rendering of Box state change`() = renderingTest(width = 40, height = 40) {
@@ -349,4 +354,18 @@
awaitNextRender()
Truth.assertThat(effectIsLaunched).isTrue()
}
+
+ @Test(expected = TestException::class)
+ fun `catch exception in LaunchedEffect`() {
+ runBlocking(Dispatchers.Main) {
+ composeRule.setContent {
+ LaunchedEffect(Unit) {
+ throw TestException()
+ }
+ }
+ composeRule.awaitIdle()
+ }
+ }
+
+ private class TestException : RuntimeException()
}
\ No newline at end of file
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/TestComposeWindowTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/TestComposeWindowTest.kt
index a85f9da..7fd119a 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/TestComposeWindowTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/TestComposeWindowTest.kt
@@ -23,6 +23,9 @@
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountBox
import androidx.compose.ui.Modifier
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.swing.Swing
import org.junit.Test
class TestComposeWindowTest {
@@ -41,4 +44,12 @@
}
}
}
+
+ @Test(timeout = 5000)
+ fun `disposing TestComposeWindow should not cancel coroutineContext's Job`() {
+ runBlocking(Dispatchers.Swing) {
+ val window = TestComposeWindow(100, 100, coroutineContext = coroutineContext)
+ window.dispose()
+ }
+ }
}
\ No newline at end of file
diff --git a/concurrent/futures-ktx/lint-baseline.xml b/concurrent/futures-ktx/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/concurrent/futures-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/core/core-animation-integration-tests/testapp/lint-baseline.xml b/core/core-animation-integration-tests/testapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/core/core-animation-integration-tests/testapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/core/core-animation-testing/lint-baseline.xml b/core/core-animation-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/core/core-animation-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/core/core-appdigest/lint-baseline.xml b/core/core-appdigest/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/core/core-appdigest/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/core/core-google-shortcuts/api/1.0.0-beta01.txt b/core/core-google-shortcuts/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/core/core-google-shortcuts/api/1.0.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/core/core-google-shortcuts/api/public_plus_experimental_1.0.0-beta01.txt b/core/core-google-shortcuts/api/public_plus_experimental_1.0.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/core/core-google-shortcuts/api/public_plus_experimental_1.0.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/core/core-google-shortcuts/api/res-1.0.0-beta01.txt b/core/core-google-shortcuts/api/res-1.0.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/core/core-google-shortcuts/api/res-1.0.0-beta01.txt
diff --git a/core/core-google-shortcuts/api/restricted_1.0.0-beta01.txt b/core/core-google-shortcuts/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..bdb2746
--- /dev/null
+++ b/core/core-google-shortcuts/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) androidx.core.google.shortcuts {
+
+ @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class ShortcutInfoChangeListenerImpl extends androidx.core.content.pm.ShortcutInfoChangeListener {
+ method public static androidx.core.google.shortcuts.ShortcutInfoChangeListenerImpl getInstance(android.content.Context);
+ }
+
+}
+
diff --git a/core/core-google-shortcuts/build.gradle b/core/core-google-shortcuts/build.gradle
index e89eb00..31d0cfe 100644
--- a/core/core-google-shortcuts/build.gradle
+++ b/core/core-google-shortcuts/build.gradle
@@ -33,7 +33,7 @@
dependencies {
api(KOTLIN_STDLIB)
- api("androidx.core:core:1.6.0-alpha02")
+ api(project(":core:core"))
implementation("com.google.firebase:firebase-appindexing:19.2.0")
implementation("com.google.crypto.tink:tink-android:1.5.0")
diff --git a/core/core-role/lint-baseline.xml b/core/core-role/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/core/core-role/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-core/lint-baseline.xml b/datastore/datastore-core/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/datastore/datastore-core/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-preferences-core/datastore-preferences-proto/lint-baseline.xml b/datastore/datastore-preferences-core/datastore-preferences-proto/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/datastore/datastore-preferences-core/datastore-preferences-proto/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-preferences-core/lint-baseline.xml b/datastore/datastore-preferences-core/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/datastore/datastore-preferences-core/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-preferences-rxjava2/lint-baseline.xml b/datastore/datastore-preferences-rxjava2/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/datastore/datastore-preferences-rxjava2/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-preferences-rxjava3/lint-baseline.xml b/datastore/datastore-preferences-rxjava3/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/datastore/datastore-preferences-rxjava3/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-preferences/lint-baseline.xml b/datastore/datastore-preferences/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/datastore/datastore-preferences/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-proto/lint-baseline.xml b/datastore/datastore-proto/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/datastore/datastore-proto/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-rxjava2/lint-baseline.xml b/datastore/datastore-rxjava2/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/datastore/datastore-rxjava2/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/datastore/datastore-rxjava3/lint-baseline.xml b/datastore/datastore-rxjava3/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/datastore/datastore-rxjava3/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/docs/api_guidelines.md b/docs/api_guidelines.md
index f04be61..e2662a5 100644
--- a/docs/api_guidelines.md
+++ b/docs/api_guidelines.md
@@ -41,9 +41,8 @@
* `-core` for a low-level artifact that *may* contain public APIs but is
primarily intended for use by other libraries in the group
* `-ktx` for an Kotlin artifact that exposes idiomatic Kotlin APIs as an
- extension to a Java-only library
-* `-java8` for a Java 8 artifact that exposes idiomatic Java 8 APIs as an
- extension to a Java 7 library
+ extension to a Java-only library (see
+ [additional -ktx guidance](#module-ktx))
* `-<third-party>` for an artifact that integrates an optional third-party API
surface, e.g. `-proto` or `-rxjava2`. Note that a major version is included
in the sub-feature name for third-party API surfaces where the major version
@@ -177,6 +176,25 @@
external developers and should be considered a last-resort when backporting
behavior is not feasible.
+### Kotlin extension `-ktx` libraries {#module-ktx}
+
+New libraries should prefer Kotlin sources with built-in Java compatibility via
+`@JvmName` and other affordances of the Kotlin language; however, existing Java
+sourced libraries may benefit from extending their API surface with
+Kotlin-friendly APIs in a `-ktx` library.
+
+A Kotlin extension library **may only** provide extensions for a single base
+library's API surface and its name **must** match the base library exactly. For
+example, `work:work-ktx` may only provide extensions for APIs exposed by
+`work:work`.
+
+Additionally, an extension library **must** specify an `api`-type dependency on
+the base library and **must** be versioned and released identically to the base
+library.
+
+Kotlin extension libraries _should not_ expose new functionality; they should
+only provide Kotlin-friendly versions of existing Java-facing functionality.
+
## Platform compatibility API patterns {#platform-compatibility-apis}
NOTE For all library APIs that wrap or provide parity with platform APIs,
@@ -1767,7 +1785,7 @@
For library groups with strongly related samples that want to share code.
-Gradle project name: `:foo-library:samples`
+Gradle project name: `:foo-library:foo-library-samples`
```
foo-library/
@@ -1780,10 +1798,18 @@
For library groups with complex, relatively independent sub-libraries
-Gradle project name: `:foo-library:foo-module:samples`
+Gradle project name: `:foo-library:foo-module:foo-module-samples`
```
foo-library/
foo-module/
samples/
```
+
+**Samples module configuration**
+
+Samples modules are published to GMaven so that they are available to Android
+Studio, which displays code in @Sample annotations as hover-over pop-ups.
+
+To achieve this, samples modules must declare the same MavenGroup and `publish`
+as the library(s) they are samples for.
diff --git a/docs/benchmarking.md b/docs/benchmarking.md
index 5fc0276..a4fabb1 100644
--- a/docs/benchmarking.md
+++ b/docs/benchmarking.md
@@ -133,11 +133,11 @@
#### Device
-Get an API 28+ device (Or a rooted API 27 device). The rest of this section is
-about *why* those constraints exist, skip if not interested.
+Get an API 29+ device. The rest of this section is about *why* those constraints
+exist, skip if not interested.
Simpleperf has restrictions about where it can be used - Jetpack Benchmark will
-only support API 28+ for now, due to
+only support API 29+ for now, due to
[platform/simpleperf constraints](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/android_application_profiling.md#prepare-an-android-application)
(see last subsection titled "If you want to profile Java code"). Summary is:
@@ -148,9 +148,13 @@
- 26 (O): Requires compiled Java code, and wrapper script. We haven't
investigated support.
-- 27 (P): Can profile all Java code, but requires `userdebug`/rooted device
+- 27 (O.1): Can profile all Java code, but requires `userdebug`/rooted device
-- \>=28 (Q): Can profile all Java code, requires profileable (or
+- 28 (P): Can profile all Java code, requires debuggable (or
+ `userdebug`/rooted device, but this appears to not be supported by scripts
+ currently)
+
+- \>=29 (Q): Can profile all Java code, requires profileable or debuggable (or
`userdebug`/rooted device)
We aren't planning to support profiling debuggable APK builds, since they're
diff --git a/docs/branching.md b/docs/branching.md
index 074a54c..dd23ec5 100644
--- a/docs/branching.md
+++ b/docs/branching.md
@@ -1,15 +1,20 @@
-# AndroidX Branch Workflow
+# Branch workflow
[TOC]
-## Single Development Branch [androidx-main]
+## Single Development Branch [`aosp/androidx-main`]
-All feature development occurs in the public AndroidX master dev branch of the
+All feature development occurs in the public main development branch of the
Android Open Source Project: `androidx-main`. This branch serves as the central
-location and source of truth for all AndroidX library source code. All alpha and
-beta version development, builds, and releases will be done ONLY in this branch.
+location and source of truth for all AndroidX library source code. All `alpha`
+and `beta` version work -- development, builds, and releases -- will be done
+ONLY in this branch.
-## Release Branches [androidx-\<feature\>-release]
+## Release Branches [`aosp/androidx-\<feature\>-release`]
+
+Release branches are used for stabilitization of a library and support of a
+previous stable release. With one development branch, this is how AndroidX
+provides support for the previous `rc` or stable version.
When a library updates to rc (release-candidate) or stable, that library version
will be snapped over to that library’s release branch. If that release branch
@@ -19,21 +24,13 @@
Release branches have the following properties:
-* A release branch will contain rc or stable versions of libraries.
-* Release branches are internal branches.
-* Release branches can **ONLY** be changed through
- cherry-picks
-* Bug-fixes and updates to that rc or stable version will need to be
- individually cherry-picked
-* No alpha or beta versions will exist in a release branch.
-* Toolchain and other library wide changes to androidx-main will be synced to
- each release branch.
+* A release branch will contain `rc` or `stable` versions of libraries
+* Release branches can **ONLY** be changed through cherry-picks
+* Bug fixes and updates to `rc` or stable versions must be cherry-picked
+* No `alpha` or `beta` versions will exist in a release branch.
+* Toolchain and other library wide changes to `androidx-main` will be synced
+ to each release branch.
* Release branches will have the naming format
`androidx-<feature-name>-release`
* Release branches will be re-snapped from `androidx-main` for each new minor
- version release (for example, releasing 2.2.0-rc01 after 2.1.0)
-
-## Platform Developement and AndroidX [androidx-platform-dev]
-
-Platform specific development is done using our INTERNAL platform development
-branch `androidx-platform-dev`.
+ version release (for example, releasing `2.2.0-rc01` after `2.1.0`)
diff --git a/docs/kdoc_guidelines.md b/docs/kdoc_guidelines.md
index ef33b04..72f91eb 100644
--- a/docs/kdoc_guidelines.md
+++ b/docs/kdoc_guidelines.md
@@ -179,6 +179,27 @@
*/
```
+### Don't use angle brackets for `@param`
+
+Instead of:
+
+```kotlin {.bad}
+/**
+ * @param <T> my cool param
+ */
+```
+
+Do this:
+
+```kotlin {.good}
+/**
+ * * @param T my cool param
+ */
+```
+
+This syntax is correct is Javadoc, but angle brackets aren't used in KDoc
+([@param reference guide](https://kotlinlang.org/docs/kotlin-doc.html#param-name)).
+
## Javadoc - KDoc differences
Some tags are shared between Javadoc and KDoc, such as `@param`, but there are
diff --git a/docs/onboarding.md b/docs/onboarding.md
index 5715972..f8dcafa 100644
--- a/docs/onboarding.md
+++ b/docs/onboarding.md
@@ -13,9 +13,10 @@
## Workstation setup {#setup}
-You will need to install the `repo` tool, which is used for Git branch and
-commit management. If you want to learn more about `repo`, see the
-[Repo Command Reference](https://source.android.com/setup/develop/repo).
+You will need to install the
+[`repo`](https://source.android.com/setup/develop#repo) tool, which is used for
+Git branch and commit management. If you want to learn more about `repo`, see
+the [Repo Command Reference](https://source.android.com/setup/develop/repo).
### Linux and MacOS {#setup-linux-mac}
@@ -210,7 +211,10 @@
```
The `--cbr` switch automatically picks the current repo branch for upload. The
-`-t` switch sets the Gerrit topic to the branch name, e.g. `my-branch-name`.
+`-t` switch sets the Gerrit topic to the branch name, e.g. `my-branch-name`. You
+can refer to the
+[Android documentation](https://source.android.com/setup/create/coding-tasks#workflow)
+for a high level overview of this basic workflow.
NOTE If you encounter issues with `repo upload`, consider running upload with
trace enabled, e.g. `GIT_DAPPER_TRACE=1 repo --trace upload . --cbr -y`. These
diff --git a/docs/policies.md b/docs/policies.md
index 35b7aaa..ffe656f 100644
--- a/docs/policies.md
+++ b/docs/policies.md
@@ -15,7 +15,7 @@
Libraries developed in AndroidX follow a consistent project naming and directory
structure.
-Library groups should organize their modules into directories and module names
+Library groups should organize their projects into directories and project names
(in brackets) as:
```
@@ -39,6 +39,27 @@
testapp/ [navigation:integration-tests:testapp]
```
+### Project creator script {#project-creator}
+
+Note: The terms _project_, _module_, and _library_ are often used
+interchangeably within AndroidX, with project being the technical term used by
+Gradle to describe a build target, e.g. a library that maps to a single AAR.
+
+New projects can be created using our
+[project creation script](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:development/project-creator/?q=project-creator&ss=androidx%2Fplatform%2Fframeworks%2Fsupport)
+available in our repo.
+
+It will create a new project with the proper structure and configuration based
+on your project needs!
+
+To use it:
+
+```sh
+cd ~/androidx-main/framework/support && \
+cd development/project-creator && \
+./create_project.py androidx.foo foo-bar
+```
+
## Terminology {#terminology}
**Artifact**
@@ -91,24 +112,6 @@
}
```
-#### Finalizing for release {#finalizing-for-release}
-
-When the artifact is ready for release, its versioned API file should be
-finalized to ensure that the subsequent versioned release conforms to the
-versioning policies.
-
-```
-./gradlew <module>:finalizeApi
-```
-
-This will prevent any subsequent changes to the API surface until the artifact
-version is updated. To update the artifact version and allow changes within the
-semantic versioning contract, simply update the version string in the artifact's
-`build.gradle` (see [Workflow](#workflow) introduction).
-
-To avoid breaking the development workflow, we recommend that API finalization
-and version string updates be submitted as a single CL.
-
## Dependencies {#dependencies}
Artifacts may depend on other artifacts within AndroidX as well as sanctioned
@@ -130,6 +133,9 @@
only have implementation-type dependencies, your artifact may carry either the
`alpha` or `beta` suffix.
+Note: This does not apply to test dependencies: suffixes of test dependencies do
+_not_ carry over to your artifact.
+
#### Pinned versions {#pinned-versions}
To avoid issues with dependency versioning, consider pinning your artifact's
diff --git a/docs/versioning.md b/docs/versioning.md
index 27efde7..3c1424a 100644
--- a/docs/versioning.md
+++ b/docs/versioning.md
@@ -239,13 +239,16 @@
granted for new features, non-trivial API changes, significant refactorings, or
any changes likely to introduce additional functional instability. Requests for
exceptions **must** be accompanied by a justification explaining why the change
-cannot be made in a future minor version.
+cannot be made in a future minor version. This policy does not apply to
+additions of `@Experimental` APIs or changes to `@Experimental` APIs.
#### Checklist for moving to `beta01` {#beta-checklist}
* API surface
* Entire API surface has been reviewed by API Council
* All APIs from alpha undergoing deprecate/remove cycle must be removed
+ * The final removal of a `@Deprecated` API must occur in alpha, not in
+ Beta.
* Testing
* All public APIs are tested
* All pre-submit and post-submit tests are enabled (e.g. all suppressions
@@ -264,10 +267,13 @@
* API surface
* May not add, remove, or change APIs unless granted an exception by API
Council following the beta API change exception request process
- * Must go through the full `@Deprecate` and hard-removal cycle in separate
- `beta` releases for any exception-approved API removals or changes
- * May not remove `@Experimental` from experimental APIs, see previous item
- regarding new APIs
+ * Must go through the full `@Deprecate` and hard-removal cycle in
+ separate `beta` releases for any exception-approved API removals or
+ changes
+ * May not remove `@Experimental` from experimental APIs, as this would
+ amount to an API addition
+ * **May** add new `@Experimental` APIs and change existing `@Experimental`
+ APIs
### RC {#rc}
diff --git a/dynamic-animation/dynamic-animation-ktx/lint-baseline.xml b/dynamic-animation/dynamic-animation-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/dynamic-animation/dynamic-animation-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/emoji/bundled/lint-baseline.xml b/emoji/bundled/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/emoji/bundled/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/emoji2/emoji2-benchmark/lint-baseline.xml b/emoji2/emoji2-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/emoji2/emoji2-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/enterprise/feedback/lint-baseline.xml b/enterprise/feedback/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/enterprise/feedback/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/enterprise/feedback/testing/lint-baseline.xml b/enterprise/feedback/testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/enterprise/feedback/testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/fragment/fragment-ktx/lint-baseline.xml b/fragment/fragment-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/fragment/fragment-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/fragment/fragment-lint/lint-baseline.xml b/fragment/fragment-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/fragment/fragment-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/fragment/fragment-testing-lint/lint-baseline.xml b/fragment/fragment-testing-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/fragment/fragment-testing-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/fragment/fragment-testing/lint-baseline.xml b/fragment/fragment-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/fragment/fragment-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/fragment/fragment-truth/lint-baseline.xml b/fragment/fragment-truth/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/fragment/fragment-truth/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/hilt/hilt-common/lint-baseline.xml b/hilt/hilt-common/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/hilt/hilt-common/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/hilt/hilt-compiler/lint-baseline.xml b/hilt/hilt-compiler/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/hilt/hilt-compiler/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/hilt/hilt-navigation-fragment/lint-baseline.xml b/hilt/hilt-navigation-fragment/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/hilt/hilt-navigation-fragment/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/hilt/hilt-work/lint-baseline.xml b/hilt/hilt-work/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/hilt/hilt-work/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/hilt/integration-tests/viewmodelapp/lint-baseline.xml b/hilt/integration-tests/viewmodelapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/hilt/integration-tests/viewmodelapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/hilt/integration-tests/workerapp/lint-baseline.xml b/hilt/integration-tests/workerapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/hilt/integration-tests/workerapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/inspection/inspection-gradle-plugin/lint-baseline.xml b/inspection/inspection-gradle-plugin/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/inspection/inspection-gradle-plugin/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/interpolator/interpolator/lint-baseline.xml b/interpolator/interpolator/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/interpolator/interpolator/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/jetifier/jetifier/core/lint-baseline.xml b/jetifier/jetifier/core/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/jetifier/jetifier/core/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/jetifier/jetifier/preprocessor/lint-baseline.xml b/jetifier/jetifier/preprocessor/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/jetifier/jetifier/preprocessor/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/jetifier/jetifier/processor/lint-baseline.xml b/jetifier/jetifier/processor/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/jetifier/jetifier/processor/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/jetifier/jetifier/standalone/lint-baseline.xml b/jetifier/jetifier/standalone/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/jetifier/jetifier/standalone/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/leanback/leanback-paging/lint-baseline.xml b/leanback/leanback-paging/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/leanback/leanback-paging/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/leanback/leanback-tab/lint-baseline.xml b/leanback/leanback-tab/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/leanback/leanback-tab/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/integration-tests/incrementality/lint-baseline.xml b/lifecycle/integration-tests/incrementality/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/lifecycle/integration-tests/incrementality/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/integration-tests/kotlintestapp/lint-baseline.xml b/lifecycle/integration-tests/kotlintestapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/integration-tests/kotlintestapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-common-java8/lint-baseline.xml b/lifecycle/lifecycle-common-java8/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/lifecycle/lifecycle-common-java8/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-compiler/lint-baseline.xml b/lifecycle/lifecycle-compiler/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/lifecycle/lifecycle-compiler/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-livedata-core-ktx-lint/lint-baseline.xml b/lifecycle/lifecycle-livedata-core-ktx-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/lifecycle/lifecycle-livedata-core-ktx-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-livedata-core-ktx/lint-baseline.xml b/lifecycle/lifecycle-livedata-core-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-livedata-core-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-livedata-core-truth/lint-baseline.xml b/lifecycle/lifecycle-livedata-core-truth/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-livedata-core-truth/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/lint-baseline.xml b/lifecycle/lifecycle-reactivestreams-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-reactivestreams-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-runtime-ktx-lint/lint-baseline.xml b/lifecycle/lifecycle-runtime-ktx-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/lifecycle/lifecycle-runtime-ktx-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-runtime-ktx/lint-baseline.xml b/lifecycle/lifecycle-runtime-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-runtime-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-runtime-testing/lint-baseline.xml b/lifecycle/lifecycle-runtime-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-runtime-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-service/lint-baseline.xml b/lifecycle/lifecycle-service/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-service/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-viewmodel-ktx/lint-baseline.xml b/lifecycle/lifecycle-viewmodel-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-viewmodel-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lifecycle/lifecycle-viewmodel/lint-baseline.xml b/lifecycle/lifecycle-viewmodel/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/lifecycle/lifecycle-viewmodel/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/lint-checks/integration-tests/build.gradle b/lint-checks/integration-tests/build.gradle
index a738ab8..c7f4c61 100644
--- a/lint-checks/integration-tests/build.gradle
+++ b/lint-checks/integration-tests/build.gradle
@@ -14,11 +14,6 @@
* limitations under the License.
*/
-import androidx.build.AndroidXGradlePropertiesKt
-import androidx.build.BuildOnServerKt
-import androidx.build.StudioType
-import androidx.build.dependencyTracker.AffectedModuleDetector
-import androidx.build.uptodatedness.EnableCachingKt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import static androidx.build.dependencies.DependenciesKt.KOTLIN_STDLIB
@@ -84,36 +79,3 @@
}
}
}
-
-def lintOutputFile = project.file("${buildDir}/reports/lint-results-debug.xml")
-def lintOutputFileNormalized = project.file("${buildDir}/lint-results-normalized/lint-results-debug.xml.normalized")
-
-def normalizeLintOutput = tasks.register("normalizeLintOutput", Copy) {
- def supportRootFolder = project.rootProject.ext.supportRootFolder
- from(lintOutputFile) {
- filter { line ->
- return line.replace(supportRootFolder.getAbsolutePath(), "\$SUPPORT")
- }
- }
- into(lintOutputFileNormalized.parentFile)
- rename(".*", lintOutputFileNormalized.name)
- dependsOn("lintDebug")
-}
-
-def validateLint = tasks.register("validateLint", CompareFilesTask) { task ->
- task.actualFile = lintOutputFileNormalized
- // Make validateLint a no-op, but still build and run lint itself on playground builds.
- // Due to b/186918949, expected-lint-results.xml provides the incorrect output for playground
- // builds, causing lint-checks:integration-tests:validateLint to fail.
- def studioType = AndroidXGradlePropertiesKt.studioType(project.rootProject)
- if (studioType == StudioType.PLAYGROUND) {
- task.expectedFile = lintOutputFileNormalized
- } else {
- task.expectedFile = project.file("expected-lint-results.xml")
- }
- EnableCachingKt.cacheEvenIfNoOutputs(task)
- dependsOn(normalizeLintOutput)
- AffectedModuleDetector.configureTaskGuard(task)
-}
-
-BuildOnServerKt.addToBuildOnServer(project, validateLint)
diff --git a/lint-checks/integration-tests/expected-lint-results.xml b/lint-checks/integration-tests/expected-lint-results.xml
index 79b7190..698b8cd 100644
--- a/lint-checks/integration-tests/expected-lint-results.xml
+++ b/lint-checks/integration-tests/expected-lint-results.xml
@@ -20,6 +20,22 @@
<issue
id="ClassVerificationFailure"
severity="Error"
+ message="This call references a method added in API level 30; however, the containing class androidx.AutofixUnsafeConstructorReferenceJava is reachable from earlier API levels and will fail run-time class verification."
+ category="Correctness"
+ priority="5"
+ summary="Even in cases where references to new APIs are gated on SDK_INT checks, run-time class verification will still fail on references to APIs that may not be available at run time, including platform APIs introduced after a library's minSdkVersion."
+ explanation="The Java language requires a virtual machine to verify the class files it
loads and executes. A class may fail verification for a wide variety of
reasons, but in practice it‘s usually because the class’s code refers to
unknown classes or methods.

References to APIs added after a library's minSdkVersion -- regardless of
any surrounding version checks -- will fail run-time class verification if
the API does not exist on the device, leading to reduced run-time
performance.

Gating references on SDK checks alone DOES NOT address class verification
failures.

To prevent class verification failures, references to new APIs must be
moved to inner classes that are only initialized inside of an appropriate
SDK check.

For example, if our minimum SDK is 14 and platform method a.x(params...)
was added in SDK 16, the method call must be moved to an inner class like:

@RequiresApi(16)
private static class Api16Impl{
 @DoNotInline
 static void callX(params...) {
 a.x(params...);
 }
}

The call site is changed from a.x(params...) to Api16Impl.callX(params).

Since ART will only try to optimize Api16Impl when it's on the execution
path, we are guaranteed to have a.x(...) available.

In addition, optimizers like R8 or Proguard may inline the method in the
separate class and replace the wrapper call with the actual call, so you
must disable inlining using the @DoNotInline annotation.

Failure to do the above may result in overall performance degradation."
+ errorLine1=" AccessibilityNodeInfo node = new AccessibilityNodeInfo(new View(context), 1);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="$SUPPORT/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeConstructorReferenceJava.java"
+ line="35"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="ClassVerificationFailure"
+ severity="Error"
message="This call references a method added in API level 23; however, the containing class androidx.AutofixUnsafeGenericMethodReferenceJava is reachable from earlier API levels and will fail run-time class verification."
category="Correctness"
priority="5"
diff --git a/lint-checks/tests/lint-baseline.xml b/lint-checks/tests/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/lint-checks/tests/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/loader/loader-ktx/lint-baseline.xml b/loader/loader-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/loader/loader-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/loader/loader/lint-baseline.xml b/loader/loader/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/loader/loader/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/localbroadcastmanager/localbroadcastmanager/lint-baseline.xml b/localbroadcastmanager/localbroadcastmanager/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/localbroadcastmanager/localbroadcastmanager/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media/version-compat-tests/current/client/lint-baseline.xml b/media/version-compat-tests/current/client/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media/version-compat-tests/current/client/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media/version-compat-tests/current/service/lint-baseline.xml b/media/version-compat-tests/current/service/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media/version-compat-tests/current/service/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media/version-compat-tests/previous/client/lint-baseline.xml b/media/version-compat-tests/previous/client/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media/version-compat-tests/previous/client/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media/version-compat-tests/previous/service/lint-baseline.xml b/media/version-compat-tests/previous/service/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media/version-compat-tests/previous/service/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media2/media2-exoplayer/lint-baseline.xml b/media2/media2-exoplayer/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media2/media2-exoplayer/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media2/media2-session/version-compat-tests/current/client/lint-baseline.xml b/media2/media2-session/version-compat-tests/current/client/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media2/media2-session/version-compat-tests/current/client/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media2/media2-session/version-compat-tests/current/service/lint-baseline.xml b/media2/media2-session/version-compat-tests/current/service/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media2/media2-session/version-compat-tests/current/service/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media2/media2-session/version-compat-tests/previous/client/lint-baseline.xml b/media2/media2-session/version-compat-tests/previous/client/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media2/media2-session/version-compat-tests/previous/client/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/media2/media2-session/version-compat-tests/previous/service/lint-baseline.xml b/media2/media2-session/version-compat-tests/previous/service/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/media2/media2-session/version-compat-tests/previous/service/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/benchmark/lint-baseline.xml b/navigation/benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-common-ktx/lint-baseline.xml b/navigation/navigation-common-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-common-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-common/api/current.txt b/navigation/navigation-common/api/current.txt
index 3b56519..5f8904b 100644
--- a/navigation/navigation-common/api/current.txt
+++ b/navigation/navigation-common/api/current.txt
@@ -302,7 +302,6 @@
@androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
method public androidx.navigation.NavGraph createDestination();
- method public androidx.navigation.NavDestination? navigate(androidx.navigation.NavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
}
public final class NavOptions {
diff --git a/navigation/navigation-common/api/public_plus_experimental_current.txt b/navigation/navigation-common/api/public_plus_experimental_current.txt
index 4d3a4dc..5159fc4 100644
--- a/navigation/navigation-common/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-common/api/public_plus_experimental_current.txt
@@ -343,7 +343,6 @@
@androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
method public androidx.navigation.NavGraph createDestination();
- method public androidx.navigation.NavDestination? navigate(androidx.navigation.NavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
}
public final class NavOptions {
diff --git a/navigation/navigation-common/api/restricted_current.txt b/navigation/navigation-common/api/restricted_current.txt
index 3b56519..5f8904b 100644
--- a/navigation/navigation-common/api/restricted_current.txt
+++ b/navigation/navigation-common/api/restricted_current.txt
@@ -302,7 +302,6 @@
@androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
method public androidx.navigation.NavGraph createDestination();
- method public androidx.navigation.NavDestination? navigate(androidx.navigation.NavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
}
public final class NavOptions {
diff --git a/navigation/navigation-common/build.gradle b/navigation/navigation-common/build.gradle
index 5ecb6d0..fe1af8a2 100644
--- a/navigation/navigation-common/build.gradle
+++ b/navigation/navigation-common/build.gradle
@@ -36,6 +36,8 @@
implementation("androidx.collection:collection-ktx:1.1.0")
api(KOTLIN_STDLIB)
+ testImplementation(project(":navigation:navigation-testing"))
+ testImplementation("androidx.arch.core:core-testing:2.1.0")
testImplementation(JUNIT)
testImplementation(MOCKITO_CORE)
testImplementation(TRUTH)
diff --git a/navigation/navigation-common/lint-baseline.xml b/navigation/navigation-common/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-common/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphNavigator.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphNavigator.kt
index 0527a9b..4b58555 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphNavigator.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavGraphNavigator.kt
@@ -15,9 +15,6 @@
*/
package androidx.navigation
-import android.os.Bundle
-import java.lang.IllegalArgumentException
-
/**
* A Navigator built specifically for [NavGraph] elements. Handles navigating to the
* correct destination when the NavGraph is the target of navigation actions.
@@ -44,11 +41,22 @@
* @throws IllegalArgumentException if given destination is not a child of the current navgraph
*/
override fun navigate(
- destination: NavGraph,
- args: Bundle?,
+ entries: List<NavBackStackEntry>,
navOptions: NavOptions?,
navigatorExtras: Extras?
- ): NavDestination? {
+ ) {
+ for (entry in entries) {
+ navigate(entry, navOptions, navigatorExtras)
+ }
+ }
+
+ private fun navigate(
+ entry: NavBackStackEntry,
+ navOptions: NavOptions?,
+ navigatorExtras: Extras?
+ ) {
+ val destination = entry.destination as NavGraph
+ val args = entry.arguments
val startId = destination.startDestinationId
val startRoute = destination.startDestinationRoute
check(startId != 0 || startRoute != null) {
@@ -68,15 +76,10 @@
val navigator = navigatorProvider.getNavigator<Navigator<NavDestination>>(
startDestination.navigatorName
)
- return navigator.navigate(
+ val startDestinationEntry = state.createBackStackEntry(
startDestination,
- startDestination.addInDefaultArgs(args),
- navOptions,
- navigatorExtras
+ startDestination.addInDefaultArgs(args)
)
- }
-
- override fun popBackStack(): Boolean {
- return true
+ navigator.navigate(listOf(startDestinationEntry), navOptions, navigatorExtras)
}
}
\ No newline at end of file
diff --git a/navigation/navigation-common/src/test/java/androidx/navigation/NavGraphNavigatorTest.kt b/navigation/navigation-common/src/test/java/androidx/navigation/NavGraphNavigatorTest.kt
index be1b914..5cd574a 100644
--- a/navigation/navigation-common/src/test/java/androidx/navigation/NavGraphNavigatorTest.kt
+++ b/navigation/navigation-common/src/test/java/androidx/navigation/NavGraphNavigatorTest.kt
@@ -17,9 +17,11 @@
package androidx.navigation
import androidx.annotation.IdRes
+import androidx.arch.core.executor.testing.InstantTaskExecutorRule
+import androidx.navigation.testing.TestNavigatorState
import com.google.common.truth.Truth.assertThat
-import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -34,8 +36,13 @@
private const val SECOND_DESTINATION_ID = 2
}
+ @get:Rule
+ val instantTaskExecutorRule = InstantTaskExecutorRule()
+
private lateinit var provider: NavigatorProvider
+ private lateinit var noOpState: TestNavigatorState
private lateinit var noOpNavigator: NoOpNavigator
+ private lateinit var navGraphState: TestNavigatorState
private lateinit var navGraphNavigator: NavGraphNavigator
@Before
@@ -48,6 +55,10 @@
}
)
}
+ noOpState = TestNavigatorState()
+ noOpNavigator.onAttach(noOpState)
+ navGraphState = TestNavigatorState()
+ navGraphNavigator.onAttach(navGraphState)
}
private fun createFirstDestination() = noOpNavigator.createDestination().apply {
@@ -74,92 +85,17 @@
id = 2 // can't match id of first destination or the start destination
setStartDestination(0)
}
- navGraphNavigator.navigate(graph, null, null, null)
+ val entry = navGraphState.createBackStackEntry(graph, null)
+ navGraphNavigator.navigate(listOf(entry), null, null)
}
@Test
fun navigate() {
val destination = createFirstDestination()
val graph = createGraphWithDestination(destination)
- assertThat(navGraphNavigator.navigate(graph, null, null, null))
- .isEqualTo(destination)
- }
-
- @Test
- fun navigateThenPop() {
- val destination = createFirstDestination()
- val graph = createGraphWithDestination(destination)
- assertThat(navGraphNavigator.navigate(graph, null, null, null))
- .isEqualTo(destination)
- val success = navGraphNavigator.popBackStack()
- assertWithMessage("popBackStack should return true")
- .that(success)
- .isTrue()
- }
-
- @Test
- fun navigateSingleTopOnEmptyStack() {
- val destination = createFirstDestination()
- val graph = createGraphWithDestination(destination)
- // singleTop should still show as added on an empty stack
- assertThat(
- navGraphNavigator.navigate(
- graph, null,
- NavOptions.Builder().setLaunchSingleTop(true).build(), null
- )
- )
- .isEqualTo(destination)
- }
-
- @Test
- fun navigateSingleTop() {
- val destination = createFirstDestination()
- val graph = createGraphWithDestination(destination)
- assertThat(navGraphNavigator.navigate(graph, null, null, null))
- .isEqualTo(destination)
- assertThat(
- navGraphNavigator.navigate(
- graph, null,
- NavOptions.Builder().setLaunchSingleTop(true).build(), null
- )
- )
- .isEqualTo(destination)
- }
-
- @Test
- fun navigateSingleTopNotTop() {
- val destination = createFirstDestination()
- val graph = createGraphWithDestination(destination)
- val secondDestination = createSecondDestination()
- val secondGraph = createGraphWithDestination(secondDestination).apply {
- id = SECOND_DESTINATION_ID
- }
- assertThat(navGraphNavigator.navigate(graph, null, null, null))
- .isEqualTo(destination)
- assertThat(
- navGraphNavigator.navigate(
- secondGraph, null,
- NavOptions.Builder().setLaunchSingleTop(true).build(), null
- )
- )
- .isEqualTo(secondDestination)
- }
-
- @Test
- fun navigateSingleTopNested() {
- val destination = createFirstDestination()
- val nestedGraph = createGraphWithDestination(destination).apply {
- id = FIRST_DESTINATION_ID
- }
- val graph = createGraphWithDestination(nestedGraph)
- assertThat(navGraphNavigator.navigate(graph, null, null, null))
- .isEqualTo(destination)
- assertThat(
- navGraphNavigator.navigate(
- graph, null,
- NavOptions.Builder().setLaunchSingleTop(true).build(), null
- )
- )
- .isEqualTo(destination)
+ val entry = navGraphState.createBackStackEntry(graph, null)
+ navGraphNavigator.navigate(listOf(entry), null, null)
+ assertThat(noOpState.backStack.value.map { it.destination })
+ .containsExactly(destination)
}
}
diff --git a/navigation/navigation-dynamic-features-fragment/lint-baseline.xml b/navigation/navigation-dynamic-features-fragment/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-dynamic-features-fragment/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigator.kt b/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigator.kt
index 574c877..a3ac6d7 100644
--- a/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigator.kt
+++ b/navigation/navigation-dynamic-features-fragment/src/main/java/androidx/navigation/dynamicfeatures/fragment/DynamicFragmentNavigator.kt
@@ -17,11 +17,10 @@
package androidx.navigation.dynamicfeatures.fragment
import android.content.Context
-import android.os.Bundle
import android.util.AttributeSet
import androidx.core.content.withStyledAttributes
import androidx.fragment.app.FragmentManager
-import androidx.navigation.NavDestination
+import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
import androidx.navigation.NavigatorProvider
@@ -43,21 +42,32 @@
override fun createDestination(): Destination = Destination(this)
override fun navigate(
- destination: FragmentNavigator.Destination,
- args: Bundle?,
+ entries: List<NavBackStackEntry>,
navOptions: NavOptions?,
navigatorExtras: Navigator.Extras?
- ): NavDestination? {
+ ) {
+ for (entry in entries) {
+ navigate(entry, navOptions, navigatorExtras)
+ }
+ }
+
+ private fun navigate(
+ entry: NavBackStackEntry,
+ navOptions: NavOptions?,
+ navigatorExtras: Navigator.Extras?
+ ) {
+ val destination = entry.destination
+ val args = entry.arguments
val extras = navigatorExtras as? DynamicExtras
if (destination is Destination) {
val moduleName = destination.moduleName
if (moduleName != null && installManager.needsInstall(moduleName)) {
- return installManager.performInstall(destination, args, extras, moduleName)
+ installManager.performInstall(destination, args, extras, moduleName)
+ return
}
}
- return super.navigate(
- destination,
- args,
+ super.navigate(
+ listOf(entry),
navOptions,
if (extras != null) extras.destinationExtras else navigatorExtras
)
diff --git a/navigation/navigation-dynamic-features-runtime/build.gradle b/navigation/navigation-dynamic-features-runtime/build.gradle
index 2b45ff2..09812400 100644
--- a/navigation/navigation-dynamic-features-runtime/build.gradle
+++ b/navigation/navigation-dynamic-features-runtime/build.gradle
@@ -37,6 +37,8 @@
api(PLAY_CORE)
api(KOTLIN_STDLIB)
+ testImplementation(project(":navigation:navigation-testing"))
+ testImplementation("androidx.arch.core:core-testing:2.1.0")
testImplementation(ANDROIDX_TEST_CORE)
testImplementation(ANDROIDX_TEST_EXT_JUNIT)
testImplementation(ANDROIDX_TEST_RUNNER)
diff --git a/navigation/navigation-dynamic-features-runtime/lint-baseline.xml b/navigation/navigation-dynamic-features-runtime/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-dynamic-features-runtime/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicGraphNavigator.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicGraphNavigator.kt
index 04ec5fa..1aa62d6 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicGraphNavigator.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicGraphNavigator.kt
@@ -21,6 +21,7 @@
import android.util.AttributeSet
import androidx.annotation.RestrictTo
import androidx.core.content.withStyledAttributes
+import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination
import androidx.navigation.NavGraph
import androidx.navigation.NavGraphNavigator
@@ -58,20 +59,32 @@
* module has successfully been installed.
*/
override fun navigate(
- destination: NavGraph,
- args: Bundle?,
+ entries: List<NavBackStackEntry>,
navOptions: NavOptions?,
navigatorExtras: Extras?
- ): NavDestination? {
+ ) {
+ for (entry in entries) {
+ navigate(entry, navOptions, navigatorExtras)
+ }
+ }
+
+ private fun navigate(
+ entry: NavBackStackEntry,
+ navOptions: NavOptions?,
+ navigatorExtras: Extras?
+ ) {
+ val destination = entry.destination
+ val args = entry.arguments
val extras = if (navigatorExtras is DynamicExtras) navigatorExtras else null
if (destination is DynamicNavGraph) {
val moduleName = destination.moduleName
if (moduleName != null && installManager.needsInstall(moduleName)) {
- return installManager.performInstall(destination, args, extras, moduleName)
+ installManager.performInstall(destination, args, extras, moduleName)
+ return
}
}
- return super.navigate(
- destination, args, navOptions,
+ super.navigate(
+ listOf(entry), navOptions,
if (extras != null) extras.destinationExtras else navigatorExtras
)
}
@@ -110,7 +123,7 @@
internal fun navigateToProgressDestination(
dynamicNavGraph: DynamicNavGraph,
progressArgs: Bundle?
- ): NavDestination? {
+ ) {
var progressDestinationId = dynamicNavGraph.progressDestination
if (progressDestinationId == 0) {
progressDestinationId = installDefaultProgressDestination(dynamicNavGraph)
@@ -124,7 +137,8 @@
val navigator = navigatorProvider.getNavigator<Navigator<NavDestination>>(
progressDestination.navigatorName
)
- return navigator.navigate(progressDestination, progressArgs, null, null)
+ val entry = state.createBackStackEntry(progressDestination, progressArgs)
+ navigator.navigate(listOf(entry), null, null)
}
/**
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicInstallManager.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicInstallManager.kt
index 0d14629e..eab3688 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicInstallManager.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicInstallManager.kt
@@ -79,8 +79,9 @@
val dynamicNavGraph = DynamicNavGraph.getOrThrow(destination)
val navigator: Navigator<*> =
dynamicNavGraph.navigatorProvider[dynamicNavGraph.navigatorName]
- return if (navigator is DynamicGraphNavigator) {
+ if (navigator is DynamicGraphNavigator) {
navigator.navigateToProgressDestination(dynamicNavGraph, progressArgs)
+ return null
} else {
throw IllegalStateException(
"You must use a DynamicNavGraph to perform a module installation."
diff --git a/navigation/navigation-dynamic-features-runtime/src/test/java/androidx/navigation/dynamicfeatures/DynamicNavGraphTest.kt b/navigation/navigation-dynamic-features-runtime/src/test/java/androidx/navigation/dynamicfeatures/DynamicNavGraphTest.kt
index 73897f5..f48fdbb 100644
--- a/navigation/navigation-dynamic-features-runtime/src/test/java/androidx/navigation/dynamicfeatures/DynamicNavGraphTest.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/test/java/androidx/navigation/dynamicfeatures/DynamicNavGraphTest.kt
@@ -16,14 +16,17 @@
package androidx.navigation.dynamicfeatures
+import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.navigation.NavDestination
import androidx.navigation.NavigatorProvider
import androidx.navigation.NoOpNavigator
import androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph
import androidx.navigation.dynamicfeatures.shared.TestDynamicInstallManager
+import androidx.navigation.testing.TestNavigatorState
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -31,10 +34,15 @@
@RunWith(JUnit4::class)
class DynamicNavGraphTest {
+ @get:Rule
+ val instantTaskExecutorRule = InstantTaskExecutorRule()
+
private val progressId = 1
private lateinit var provider: NavigatorProvider
+ private lateinit var navigatorState: TestNavigatorState
private lateinit var navigator: DynamicGraphNavigator
private lateinit var dynamicNavGraph: DynamicNavGraph
+ private lateinit var noOpState: TestNavigatorState
private lateinit var noOpNavigator: NoOpNavigator
@Before
@@ -46,6 +54,8 @@
TestDynamicInstallManager()
)
provider.addNavigator(noOpNavigator)
+ noOpState = TestNavigatorState()
+ noOpNavigator.onAttach(noOpState)
dynamicNavGraph = navigator.createDestination()
}
@@ -61,7 +71,8 @@
id = progressId
}
)
- val progressDestination = navigator.navigateToProgressDestination(dynamicNavGraph, null)
+ navigator.navigateToProgressDestination(dynamicNavGraph, null)
+ val progressDestination = noOpState.backStack.value.lastOrNull()?.destination
assertNotNull(progressDestination)
progressDestination?.let {
DynamicNavGraph.getOrThrow(progressDestination)
@@ -82,7 +93,8 @@
id = progressId
}
)
- val destination = navigator.navigateToProgressDestination(dynamicNavGraph, null)
+ navigator.navigateToProgressDestination(dynamicNavGraph, null)
+ val destination = noOpState.backStack.value.lastOrNull()?.destination
assertTrue(destination?.parent is DynamicNavGraph)
}
@@ -91,6 +103,8 @@
navigator.installDefaultProgressDestination { it }
}
provider.addNavigator(navigator)
+ navigatorState = TestNavigatorState()
+ navigator.onAttach(navigatorState)
dynamicNavGraph = navigator.createDestination()
}
}
diff --git a/navigation/navigation-fragment-ktx/lint-baseline.xml b/navigation/navigation-fragment-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-fragment-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-fragment/api/current.ignore b/navigation/navigation-fragment/api/current.ignore
index e92246d..bed10fd 100644
--- a/navigation/navigation-fragment/api/current.ignore
+++ b/navigation/navigation-fragment/api/current.ignore
@@ -5,5 +5,7 @@
RemovedMethod: androidx.navigation.fragment.DialogFragmentNavigator#popBackStack():
Removed method androidx.navigation.fragment.DialogFragmentNavigator.popBackStack()
+RemovedMethod: androidx.navigation.fragment.FragmentNavigator#navigate(androidx.navigation.fragment.FragmentNavigator.Destination, android.os.Bundle, androidx.navigation.NavOptions, androidx.navigation.Navigator.Extras):
+ Removed method androidx.navigation.fragment.FragmentNavigator.navigate(androidx.navigation.fragment.FragmentNavigator.Destination,android.os.Bundle,androidx.navigation.NavOptions,androidx.navigation.Navigator.Extras)
RemovedMethod: androidx.navigation.fragment.FragmentNavigator#popBackStack():
Removed method androidx.navigation.fragment.FragmentNavigator.popBackStack()
diff --git a/navigation/navigation-fragment/api/current.txt b/navigation/navigation-fragment/api/current.txt
index ac16ffe..5f8b262 100644
--- a/navigation/navigation-fragment/api/current.txt
+++ b/navigation/navigation-fragment/api/current.txt
@@ -45,7 +45,6 @@
ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
- method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.FragmentNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
}
@androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
diff --git a/navigation/navigation-fragment/api/public_plus_experimental_current.txt b/navigation/navigation-fragment/api/public_plus_experimental_current.txt
index ac16ffe..5f8b262 100644
--- a/navigation/navigation-fragment/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-fragment/api/public_plus_experimental_current.txt
@@ -45,7 +45,6 @@
ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
- method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.FragmentNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
}
@androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
diff --git a/navigation/navigation-fragment/api/restricted_current.ignore b/navigation/navigation-fragment/api/restricted_current.ignore
index e92246d..bed10fd 100644
--- a/navigation/navigation-fragment/api/restricted_current.ignore
+++ b/navigation/navigation-fragment/api/restricted_current.ignore
@@ -5,5 +5,7 @@
RemovedMethod: androidx.navigation.fragment.DialogFragmentNavigator#popBackStack():
Removed method androidx.navigation.fragment.DialogFragmentNavigator.popBackStack()
+RemovedMethod: androidx.navigation.fragment.FragmentNavigator#navigate(androidx.navigation.fragment.FragmentNavigator.Destination, android.os.Bundle, androidx.navigation.NavOptions, androidx.navigation.Navigator.Extras):
+ Removed method androidx.navigation.fragment.FragmentNavigator.navigate(androidx.navigation.fragment.FragmentNavigator.Destination,android.os.Bundle,androidx.navigation.NavOptions,androidx.navigation.Navigator.Extras)
RemovedMethod: androidx.navigation.fragment.FragmentNavigator#popBackStack():
Removed method androidx.navigation.fragment.FragmentNavigator.popBackStack()
diff --git a/navigation/navigation-fragment/api/restricted_current.txt b/navigation/navigation-fragment/api/restricted_current.txt
index ac16ffe..5f8b262 100644
--- a/navigation/navigation-fragment/api/restricted_current.txt
+++ b/navigation/navigation-fragment/api/restricted_current.txt
@@ -45,7 +45,6 @@
ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
- method public androidx.navigation.NavDestination? navigate(androidx.navigation.fragment.FragmentNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
}
@androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
diff --git a/navigation/navigation-fragment/build.gradle b/navigation/navigation-fragment/build.gradle
index fa1132c..5837d97 100644
--- a/navigation/navigation-fragment/build.gradle
+++ b/navigation/navigation-fragment/build.gradle
@@ -31,6 +31,7 @@
api(project(":navigation:navigation-runtime"))
api(KOTLIN_STDLIB)
+ androidTestImplementation(project(":navigation:navigation-testing"))
androidTestImplementation(projectOrArtifact(":fragment:fragment-testing"))
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/navigation/navigation-fragment/lint-baseline.xml b/navigation/navigation-fragment/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-fragment/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt
index 8b7571e..2498514 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/FragmentNavigatorTest.kt
@@ -22,9 +22,11 @@
import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
+import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavOptions
import androidx.navigation.fragment.test.EmptyFragment
import androidx.navigation.fragment.test.R
+import androidx.navigation.testing.TestNavigatorState
import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
@@ -38,6 +40,7 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import kotlin.reflect.KClass
@LargeTest
@RunWith(AndroidJUnit4::class)
@@ -57,24 +60,26 @@
private lateinit var emptyActivity: EmptyActivity
private lateinit var fragmentManager: FragmentManager
+ private lateinit var navigatorState: TestNavigatorState
+ private lateinit var fragmentNavigator: FragmentNavigator
@Before
fun setup() {
emptyActivity = activityRule.activity
fragmentManager = emptyActivity.supportFragmentManager
+ navigatorState = TestNavigatorState()
+ fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
+ fragmentNavigator.onAttach(navigatorState)
}
@UiThreadTest
@Test
fun testNavigate() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination().apply {
- id = INITIAL_FRAGMENT
- setClassName(EmptyFragment::class.java.name)
- }
+ val entry = createBackStackEntry()
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Fragment should be added", fragment)
@@ -92,14 +97,11 @@
@Test
fun testNavigateWithFragmentFactory() {
fragmentManager.fragmentFactory = NonEmptyFragmentFactory()
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination().apply {
- id = INITIAL_FRAGMENT
- setClassName(NonEmptyConstructorFragment::class.java.name)
- }
+ val entry = createBackStackEntry(clazz = NonEmptyConstructorFragment::class)
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Fragment should be added")
@@ -116,14 +118,11 @@
@UiThreadTest
@Test
fun testNavigateTwice() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination().apply {
- id = INITIAL_FRAGMENT
- setClassName(EmptyFragment::class.java.name)
- }
+ val entry = createBackStackEntry()
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Fragment should be added", fragment)
@@ -137,9 +136,10 @@
)
// Now push a second fragment
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Replacement Fragment should be added", replacementFragment)
@@ -156,60 +156,55 @@
@UiThreadTest
@Test
fun testNavigateWithPopUpToThenPop() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
// Push initial fragment
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
// Push a second fragment
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val secondEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(secondEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry).inOrder()
fragmentManager.executePendingTransactions()
// Pop and then push third fragment, simulating popUpTo to initial.
- val success = fragmentNavigator.popBackStack()
- assertTrue("FragmentNavigator should return true when popping the third fragment", success)
- destination.id = THIRD_FRAGMENT
- assertThat(
- fragmentNavigator.navigate(
- destination, null,
- NavOptions.Builder().setPopUpTo(INITIAL_FRAGMENT, false).build(), null
- )
- )
- .isEqualTo(destination)
+ fragmentNavigator.popBackStack(secondEntry, false)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+ val thirdEntry = createBackStackEntry(THIRD_FRAGMENT)
+ fragmentNavigator.navigate(listOf(thirdEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, thirdEntry).inOrder()
fragmentManager.executePendingTransactions()
// Now pop the Fragment
- val popped = fragmentNavigator.popBackStack()
- assertTrue("FragmentNavigator should return true when popping the third fragment", popped)
+ fragmentNavigator.popBackStack(thirdEntry, false)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
}
@UiThreadTest
@Test
fun testSingleTopInitial() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
- fragmentNavigator.navigate(destination, null, null, null)
+ fragmentNavigator.navigate(listOf(entry), null, null)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Fragment should be added", fragment)
val lifecycle = fragment!!.lifecycle
- assertThat(
- fragmentNavigator.navigate(
- destination, null,
- NavOptions.Builder().setLaunchSingleTop(true).build(), null
- )
+ fragmentNavigator.navigate(
+ listOf(entry),
+ NavOptions.Builder().setLaunchSingleTop(true).build(),
+ null
)
- .isNull()
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Replacement Fragment should be added", replacementFragment)
@@ -234,13 +229,12 @@
@UiThreadTest
@Test
fun testSingleTop() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
// First push an initial Fragment
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val initialFragment = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Initial Fragment should be added")
@@ -248,9 +242,10 @@
.isNotNull()
// Now push the Fragment that we want to replace with a singleTop operation
- destination.id = 1
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Fragment should be added")
@@ -258,13 +253,13 @@
.isNotNull()
val lifecycle = fragment!!.lifecycle
- assertThat(
- fragmentNavigator.navigate(
- destination, null,
- NavOptions.Builder().setLaunchSingleTop(true).build(), null
- )
+ fragmentNavigator.navigate(
+ listOf(replacementEntry),
+ NavOptions.Builder().setLaunchSingleTop(true).build(),
+ null
)
- .isNull()
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Replacement Fragment should be added")
@@ -283,8 +278,10 @@
.that(lifecycle.currentState)
.isEqualTo(Lifecycle.State.DESTROYED)
- assertThat(fragmentNavigator.popBackStack())
- .isTrue()
+ fragmentNavigator.popBackStack(replacementEntry, false)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+
fragmentManager.executePendingTransactions()
assertWithMessage("Initial Fragment should be on top of back stack after pop")
.that(fragmentManager.findFragmentById(R.id.container))
@@ -297,47 +294,37 @@
@UiThreadTest
@Test
fun testPopInitial() {
- val fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
// First push an initial Fragment
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
// Now pop the initial Fragment
- val popped = fragmentNavigator.popBackStack()
- assertWithMessage(
- "FragmentNavigator should return false when popping " +
- "the initial Fragment"
- )
- .that(popped)
- .isTrue()
+ fragmentNavigator.popBackStack(entry, false)
+ assertThat(navigatorState.backStack.value)
+ .isEmpty()
}
@UiThreadTest
@Test
fun testPop() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
// First push an initial Fragment
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Fragment should be added", fragment)
// Now push the Fragment that we want to pop
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Replacement Fragment should be added", replacementFragment)
@@ -351,9 +338,10 @@
)
// Now pop the Fragment
- val popped = fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(replacementEntry, false)
fragmentManager.executePendingTransactions()
- assertTrue("FragmentNavigator should return true when popping a Fragment", popped)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
assertEquals(
"Fragment should be the primary navigation Fragment after pop",
fragment, fragmentManager.primaryNavigationFragment
@@ -363,14 +351,12 @@
@UiThreadTest
@Test
fun testPopWithSameDestinationTwice() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
// First push an initial Fragment
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Fragment should be added")
@@ -378,9 +364,10 @@
.isNotNull()
// Now push a second Fragment
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val secondEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(secondEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry).inOrder()
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Replacement Fragment should be added")
@@ -392,8 +379,10 @@
// Push the same Fragment a second time, creating a stack of two
// identical Fragments
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry, replacementEntry).inOrder()
fragmentManager.executePendingTransactions()
val fragmentToPop = fragmentManager.findFragmentById(R.id.container)
assertWithMessage("Fragment to pop should be added")
@@ -404,11 +393,10 @@
.isSameInstanceAs(fragmentToPop)
// Now pop the Fragment
- val popped = fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(replacementEntry, false)
fragmentManager.executePendingTransactions()
- assertWithMessage("FragmentNavigator should return true when popping a Fragment")
- .that(popped)
- .isTrue()
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry).inOrder()
assertWithMessage(
"Replacement Fragment should be the primary navigation Fragment " +
"after pop"
@@ -420,22 +408,21 @@
@UiThreadTest
@Test
fun testPopWithChildFragmentBackStack() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
// First push an initial Fragment
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Fragment should be added", fragment)
// Now push the Fragment that we want to pop
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Replacement Fragment should be added", replacementFragment)
@@ -458,9 +445,10 @@
}
// Now pop the Fragment
- val popped = fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(replacementEntry, false)
fragmentManager.executePendingTransactions()
- assertTrue("FragmentNavigator should return true when popping a Fragment", popped)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
assertEquals(
"Fragment should be the primary navigation Fragment after pop",
fragment, fragmentManager.primaryNavigationFragment
@@ -470,22 +458,19 @@
@UiThreadTest
@Test
fun testDeepLinkPop() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
+ val secondEntry = createBackStackEntry(SECOND_FRAGMENT)
// First push two Fragments as our 'deep link'
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ fragmentNavigator.navigate(listOf(entry, secondEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry)
// Now push the Fragment that we want to pop
- destination.id = THIRD_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
+ val thirdEntry = createBackStackEntry(THIRD_FRAGMENT)
+ fragmentNavigator.navigate(listOf(thirdEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry, thirdEntry)
fragmentManager.executePendingTransactions()
val replacementFragment = fragmentManager.findFragmentById(R.id.container)
assertNotNull("Replacement Fragment should be added", replacementFragment)
@@ -499,7 +484,7 @@
)
// Now pop the Fragment
- fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(thirdEntry, false)
fragmentManager.executePendingTransactions()
val fragment = fragmentManager.findFragmentById(R.id.container)
assertEquals(
@@ -510,156 +495,19 @@
@UiThreadTest
@Test
- fun testDeepLinkPopWithSaveState() {
- var fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
-
- // First push two Fragments as our 'deep link'
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
-
- // Now push the Fragment that we want to pop
- destination.id = THIRD_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
- fragmentManager.executePendingTransactions()
- val replacementFragment = fragmentManager.findFragmentById(R.id.container)
- assertNotNull("Replacement Fragment should be added", replacementFragment)
- assertTrue(
- "Replacement Fragment should be the correct type",
- replacementFragment is EmptyFragment
- )
- assertEquals(
- "Replacement Fragment should be the primary navigation Fragment",
- replacementFragment, fragmentManager.primaryNavigationFragment
- )
-
- // Create a new FragmentNavigator, replacing the previous one
- val savedState = fragmentNavigator.onSaveState() as Bundle
- fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- fragmentNavigator.onRestoreState(savedState)
-
- // Now pop the Fragment
- fragmentNavigator.popBackStack()
- fragmentManager.executePendingTransactions()
- val fragment = fragmentManager.findFragmentById(R.id.container)
- assertEquals(
- "Fragment should be the primary navigation Fragment after pop",
- fragment, fragmentManager.primaryNavigationFragment
- )
- }
-
- @UiThreadTest
- @Test
- fun testNavigateThenPopAfterSaveState() {
- var fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- val destination = fragmentNavigator.createDestination()
- destination.id = INITIAL_FRAGMENT
- destination.setClassName(EmptyFragment::class.java.name)
-
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
- fragmentManager.executePendingTransactions()
- var fragment = fragmentManager.findFragmentById(R.id.container)
- assertNotNull("Fragment should be added", fragment)
- assertEquals(
- "Fragment should be the correct type",
- EmptyFragment::class.java, fragment!!::class.java
- )
- assertEquals(
- "Fragment should be the primary navigation Fragment",
- fragment, fragmentManager.primaryNavigationFragment
- )
-
- // Now push a second fragment
- destination.id = SECOND_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
- fragmentManager.executePendingTransactions()
- var replacementFragment = fragmentManager.findFragmentById(R.id.container)
- assertNotNull("Replacement Fragment should be added", replacementFragment)
- assertEquals(
- "Replacement Fragment should be the correct type",
- EmptyFragment::class.java, replacementFragment!!::class.java
- )
- assertEquals(
- "Replacement Fragment should be the primary navigation Fragment",
- replacementFragment, fragmentManager.primaryNavigationFragment
- )
-
- // Create a new FragmentNavigator, replacing the previous one
- val savedState = fragmentNavigator.onSaveState() as Bundle
- fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- fragmentNavigator.onRestoreState(savedState)
-
- // Now push a third fragment after the state save
- destination.id = THIRD_FRAGMENT
- assertThat(fragmentNavigator.navigate(destination, null, null, null))
- .isEqualTo(destination)
- fragmentManager.executePendingTransactions()
- replacementFragment = fragmentManager.findFragmentById(R.id.container)
- assertNotNull("Replacement Fragment should be added", replacementFragment)
- assertTrue(
- "Replacement Fragment should be the correct type",
- replacementFragment is EmptyFragment
- )
- assertEquals(
- "Replacement Fragment should be the primary navigation Fragment",
- replacementFragment, fragmentManager.primaryNavigationFragment
- )
-
- // Now pop the Fragment
- fragmentNavigator.popBackStack()
- fragmentManager.executePendingTransactions()
- fragment = fragmentManager.findFragmentById(R.id.container)
- assertEquals(
- "Fragment should be the primary navigation Fragment after pop",
- fragment, fragmentManager.primaryNavigationFragment
- )
- }
-
- @UiThreadTest
- @Test
fun testMultipleNavigateFragmentTransactionsThenPop() {
- val fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- val destination = fragmentNavigator.createDestination()
- destination.setClassName(EmptyFragment::class.java.name)
- val destination2 = fragmentNavigator.createDestination()
- destination2.setClassName(Fragment::class.java.name)
+ val entry = createBackStackEntry()
+ val secondEntry = createBackStackEntry(SECOND_FRAGMENT, clazz = Fragment::class)
+ val thirdEntry = createBackStackEntry(THIRD_FRAGMENT)
// Push 3 fragments without executing pending transactions.
- destination.id = INITIAL_FRAGMENT
- fragmentNavigator.navigate(destination, null, null, null)
- destination2.id = SECOND_FRAGMENT
- fragmentNavigator.navigate(destination2, null, null, null)
- destination.id = THIRD_FRAGMENT
- fragmentNavigator.navigate(destination, null, null, null)
+ fragmentNavigator.navigate(listOf(entry, secondEntry, thirdEntry), null, null)
// Now pop the Fragment
- val popped = fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(thirdEntry, false)
fragmentManager.executePendingTransactions()
- assertWithMessage("FragmentNavigator should return true when popping the third fragment")
- .that(popped).isTrue()
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, secondEntry)
// We should ensure the fragment manager is on the proper fragment at the end
assertWithMessage("FragmentManager back stack should have only SECOND_FRAGMENT")
.that(fragmentManager.backStackEntryCount)
@@ -672,36 +520,176 @@
@UiThreadTest
@Test
fun testMultiplePopFragmentTransactionsThenPop() {
- val fragmentNavigator = FragmentNavigator(
- emptyActivity,
- fragmentManager, R.id.container
- )
- val destination = fragmentNavigator.createDestination()
- destination.setClassName(EmptyFragment::class.java.name)
+ val entry = createBackStackEntry()
+ val secondEntry = createBackStackEntry(SECOND_FRAGMENT)
+ val thirdEntry = createBackStackEntry(THIRD_FRAGMENT)
+ val fourthEntry = createBackStackEntry(FOURTH_FRAGMENT)
// Push 4 fragments
- destination.id = INITIAL_FRAGMENT
- fragmentNavigator.navigate(destination, null, null, null)
- destination.id = SECOND_FRAGMENT
- fragmentNavigator.navigate(destination, null, null, null)
- destination.id = THIRD_FRAGMENT
- fragmentNavigator.navigate(destination, null, null, null)
- destination.id = FOURTH_FRAGMENT
- fragmentNavigator.navigate(destination, null, null, null)
+ fragmentNavigator.navigate(
+ listOf(entry, secondEntry, thirdEntry, fourthEntry),
+ null, null
+ )
fragmentManager.executePendingTransactions()
// Pop 2 fragments without executing pending transactions.
- fragmentNavigator.popBackStack()
- fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(thirdEntry, false)
- val popped = fragmentNavigator.popBackStack()
+ fragmentNavigator.popBackStack(secondEntry, false)
fragmentManager.executePendingTransactions()
- assertTrue("FragmentNavigator should return true when popping the third fragment", popped)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+ }
+
+ @UiThreadTest
+ @Test
+ fun testSaveRestoreState() {
+ val entry = createBackStackEntry()
+
+ // First push an initial Fragment
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+ fragmentManager.executePendingTransactions()
+ val fragment = fragmentManager.findFragmentById(R.id.container)
+ assertWithMessage("Fragment should be added")
+ .that(fragment)
+ .isNotNull()
+
+ // Now push the Fragment that we want to save
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT, SavedStateFragment::class)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
+ fragmentManager.executePendingTransactions()
+ val replacementFragment = fragmentManager.findFragmentById(R.id.container)
+ assertWithMessage("Replacement Fragment should be added")
+ .that(replacementFragment)
+ .isNotNull()
+ assertWithMessage("Replacement Fragment should be the correct type")
+ .that(replacementFragment)
+ .isInstanceOf(SavedStateFragment::class.java)
+ assertWithMessage("Replacement Fragment should be the primary navigation Fragment")
+ .that(fragmentManager.primaryNavigationFragment)
+ .isSameInstanceAs(replacementFragment)
+
+ // Save some state into the replacement fragment
+ (replacementFragment as SavedStateFragment).savedState = "test"
+
+ // Now save the Fragment
+ fragmentNavigator.popBackStack(replacementEntry, true)
+ fragmentManager.executePendingTransactions()
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+ assertWithMessage("Fragment should be the primary navigation Fragment after pop")
+ .that(fragmentManager.primaryNavigationFragment)
+ .isSameInstanceAs(fragment)
+
+ // And now restore the fragment
+ val restoredEntry = navigatorState.restoreBackStackEntry(replacementEntry)
+ fragmentNavigator.navigate(
+ listOf(restoredEntry),
+ NavOptions.Builder().setRestoreState(true).build(), null
+ )
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, restoredEntry).inOrder()
+ fragmentManager.executePendingTransactions()
+ val restoredFragment = fragmentManager.findFragmentById(R.id.container)
+ assertWithMessage("Restored Fragment should be added")
+ .that(restoredFragment)
+ .isNotNull()
+ assertWithMessage("Restored Fragment should be the correct type")
+ .that(restoredFragment)
+ .isInstanceOf(SavedStateFragment::class.java)
+ assertWithMessage("Restored Fragment should be the primary navigation Fragment")
+ .that(fragmentManager.primaryNavigationFragment)
+ .isSameInstanceAs(restoredFragment)
+
+ assertWithMessage("Restored Fragment should have its state restored")
+ .that((restoredFragment as SavedStateFragment).savedState)
+ .isEqualTo("test")
+ }
+
+ @UiThreadTest
+ @Test
+ fun testSaveRestoreStateAfterSaveState() {
+ val entry = createBackStackEntry()
+
+ // First push an initial Fragment
+ fragmentNavigator.navigate(listOf(entry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+ fragmentManager.executePendingTransactions()
+ val fragment = fragmentManager.findFragmentById(R.id.container)
+ assertWithMessage("Fragment should be added")
+ .that(fragment)
+ .isNotNull()
+
+ // Now push the Fragment that we want to save
+ val replacementEntry = createBackStackEntry(SECOND_FRAGMENT, SavedStateFragment::class)
+ fragmentNavigator.navigate(listOf(replacementEntry), null, null)
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, replacementEntry).inOrder()
+ fragmentManager.executePendingTransactions()
+ val replacementFragment = fragmentManager.findFragmentById(R.id.container)
+ assertWithMessage("Replacement Fragment should be added")
+ .that(replacementFragment)
+ .isNotNull()
+ assertWithMessage("Replacement Fragment should be the correct type")
+ .that(replacementFragment)
+ .isInstanceOf(SavedStateFragment::class.java)
+ assertWithMessage("Replacement Fragment should be the primary navigation Fragment")
+ .that(fragmentManager.primaryNavigationFragment)
+ .isSameInstanceAs(replacementFragment)
+
+ // Save some state into the replacement fragment
+ (replacementFragment as SavedStateFragment).savedState = "test"
+
+ // Now save the Fragment
+ fragmentNavigator.popBackStack(replacementEntry, true)
+ fragmentManager.executePendingTransactions()
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry)
+ assertWithMessage("Fragment should be the primary navigation Fragment after pop")
+ .that(fragmentManager.primaryNavigationFragment)
+ .isSameInstanceAs(fragment)
+
+ // Create a new FragmentNavigator, replacing the previous one
+ val savedState = fragmentNavigator.onSaveState() as Bundle
+ fragmentNavigator = FragmentNavigator(
+ emptyActivity,
+ fragmentManager, R.id.container
+ )
+ fragmentNavigator.onAttach(navigatorState)
+ fragmentNavigator.onRestoreState(savedState)
+
+ // And now restore the fragment
+ val restoredEntry = navigatorState.restoreBackStackEntry(replacementEntry)
+ fragmentNavigator.navigate(
+ listOf(restoredEntry),
+ NavOptions.Builder().setRestoreState(true).build(), null
+ )
+ assertThat(navigatorState.backStack.value)
+ .containsExactly(entry, restoredEntry).inOrder()
+ fragmentManager.executePendingTransactions()
+ val restoredFragment = fragmentManager.findFragmentById(R.id.container)
+ assertWithMessage("Restored Fragment should be added")
+ .that(restoredFragment)
+ .isNotNull()
+ assertWithMessage("Restored Fragment should be the correct type")
+ .that(restoredFragment)
+ .isInstanceOf(SavedStateFragment::class.java)
+ assertWithMessage("Restored Fragment should be the primary navigation Fragment")
+ .that(fragmentManager.primaryNavigationFragment)
+ .isSameInstanceAs(restoredFragment)
+
+ assertWithMessage("Restored Fragment should have its state restored")
+ .that((restoredFragment as SavedStateFragment).savedState)
+ .isEqualTo("test")
}
@Test
fun testToString() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
val destination = fragmentNavigator.createDestination().apply {
id = INITIAL_FRAGMENT
setClassName(EmptyFragment::class.java.name)
@@ -714,7 +702,6 @@
@Test
fun testToStringNoClassName() {
- val fragmentNavigator = FragmentNavigator(emptyActivity, fragmentManager, R.id.container)
val destination = fragmentNavigator.createDestination().apply {
id = INITIAL_FRAGMENT
label = TEST_LABEL
@@ -723,6 +710,17 @@
"class=null"
assertThat(destination.toString()).isEqualTo(expected)
}
+
+ private fun createBackStackEntry(
+ destId: Int = INITIAL_FRAGMENT,
+ clazz: KClass<out Fragment> = EmptyFragment::class
+ ): NavBackStackEntry {
+ val destination = fragmentNavigator.createDestination().apply {
+ id = destId
+ setClassName(clazz.java.name)
+ }
+ return navigatorState.createBackStackEntry(destination, null)
+ }
}
class EmptyActivity : FragmentActivity() {
@@ -732,6 +730,20 @@
}
}
+class SavedStateFragment : Fragment() {
+ var savedState: String? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ savedState = savedInstanceState?.getString("savedState")
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ outState.putString("savedState", savedState)
+ }
+}
+
class NonEmptyConstructorFragment(val test: String) : Fragment()
class NonEmptyFragmentFactory : FragmentFactory() {
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt
index 4dd7e37..7e575fc 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt
@@ -23,8 +23,10 @@
import androidx.annotation.CallSuper
import androidx.annotation.IdRes
import androidx.core.content.res.use
+import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
+import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
@@ -50,7 +52,7 @@
private val fragmentManager: FragmentManager,
private val containerId: Int
) : Navigator<Destination>() {
- private val backStack = ArrayDeque<Int>()
+ private val savedIds = mutableSetOf<String>()
/**
* {@inheritDoc}
@@ -64,22 +66,41 @@
* asynchronously, so the newly visible Fragment from the back stack
* is not instantly available after this call completes.
*/
- public override fun popBackStack(): Boolean {
- if (backStack.isEmpty()) {
- return false
- }
+ override fun popBackStack(popUpTo: NavBackStackEntry, savedState: Boolean) {
if (fragmentManager.isStateSaved) {
Log.i(
TAG, "Ignoring popBackStack() call: FragmentManager has already saved its state"
)
- return false
+ return
}
- fragmentManager.popBackStack(
- generateBackStackName(backStack.size, backStack.last()),
- FragmentManager.POP_BACK_STACK_INCLUSIVE
- )
- backStack.removeLast()
- return true
+ if (savedState) {
+ val beforePopList = state.backStack.value
+ val initialEntry = beforePopList.first()
+ // Get the set of entries that are going to be popped
+ val poppedList = beforePopList.subList(
+ beforePopList.indexOf(popUpTo),
+ beforePopList.size
+ )
+ // Now go through the list in reversed order (i.e., started from the most added)
+ // and save the back stack state of each.
+ for (entry in poppedList.reversed()) {
+ if (entry == initialEntry) {
+ Log.i(
+ TAG,
+ "FragmentManager cannot save the state of the initial destination $entry"
+ )
+ } else {
+ fragmentManager.saveBackStack(entry.id)
+ savedIds += entry.id
+ }
+ }
+ } else {
+ fragmentManager.popBackStack(
+ popUpTo.id,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE
+ )
+ }
+ state.pop(popUpTo, savedState)
}
public override fun createDestination(): Destination {
@@ -126,18 +147,42 @@
* asynchronously, so the new Fragment is not instantly available
* after this call completes.
*/
- public override fun navigate(
- destination: Destination,
- args: Bundle?,
+ override fun navigate(
+ entries: List<NavBackStackEntry>,
navOptions: NavOptions?,
navigatorExtras: Navigator.Extras?
- ): NavDestination? {
+ ) {
if (fragmentManager.isStateSaved) {
Log.i(
TAG, "Ignoring navigate() call: FragmentManager has already saved its state"
)
- return null
+ return
}
+ for (entry in entries) {
+ navigate(entry, navOptions, navigatorExtras)
+ }
+ }
+
+ private fun navigate(
+ entry: NavBackStackEntry,
+ navOptions: NavOptions?,
+ navigatorExtras: Navigator.Extras?
+ ) {
+ val backStack = state.backStack.value
+ val initialNavigation = backStack.isEmpty()
+ val restoreState = (
+ navOptions != null && !initialNavigation &&
+ navOptions.shouldRestoreState() &&
+ savedIds.remove(entry.id)
+ )
+ if (restoreState) {
+ // Restore back stack does all the work to restore the entry
+ fragmentManager.restoreBackStack(entry.id)
+ state.add(entry)
+ return
+ }
+ val destination = entry.destination as Destination
+ val args = entry.arguments
var className = destination.className
if (className[0] == '.') {
className = context.packageName + className
@@ -159,15 +204,13 @@
ft.replace(containerId, frag)
ft.setPrimaryNavigationFragment(frag)
@IdRes val destId = destination.id
- val initialNavigation = backStack.isEmpty()
// TODO Build first class singleTop behavior for fragments
val isSingleTopReplacement = (
navOptions != null && !initialNavigation &&
navOptions.shouldLaunchSingleTop() &&
- backStack.last() == destId
+ backStack.last().destination.id == destId
)
- val isAdded: Boolean
- isAdded = when {
+ val isAdded = when {
initialNavigation -> {
true
}
@@ -179,15 +222,15 @@
// remove it from the back stack and put our replacement
// on the back stack in its place
fragmentManager.popBackStack(
- generateBackStackName(backStack.size, backStack.last()),
+ entry.id,
FragmentManager.POP_BACK_STACK_INCLUSIVE
)
- ft.addToBackStack(generateBackStackName(backStack.size, destId))
+ ft.addToBackStack(entry.id)
}
false
}
else -> {
- ft.addToBackStack(generateBackStackName(backStack.size + 1, destId))
+ ft.addToBackStack(entry.id)
true
}
}
@@ -199,35 +242,26 @@
ft.setReorderingAllowed(true)
ft.commit()
// The commit succeeded, update our view of the world
- return if (isAdded) {
- backStack.add(destId)
- destination
- } else {
- null
+ if (isAdded) {
+ state.add(entry)
}
}
public override fun onSaveState(): Bundle? {
- val b = Bundle()
- val backStack = backStack.toIntArray()
- b.putIntArray(KEY_BACK_STACK_IDS, backStack)
- return b
+ if (savedIds.isEmpty()) {
+ return null
+ }
+ return bundleOf(KEY_SAVED_IDS to ArrayList(savedIds))
}
public override fun onRestoreState(savedState: Bundle) {
- val backStack = savedState.getIntArray(KEY_BACK_STACK_IDS)
- if (backStack != null) {
- this.backStack.clear()
- for (destId in backStack) {
- this.backStack.add(destId)
- }
+ val savedIds = savedState.getStringArrayList(KEY_SAVED_IDS)
+ if (savedIds != null) {
+ this.savedIds.clear()
+ this.savedIds += savedIds
}
}
- private fun generateBackStackName(backStackIndex: Int, destId: Int): String {
- return "$backStackIndex-$destId"
- }
-
/**
* NavDestination specific to [FragmentNavigator]
*/
@@ -368,6 +402,6 @@
private companion object {
private const val TAG = "FragmentNavigator"
- private const val KEY_BACK_STACK_IDS = "androidx-nav-fragment:navigator:backStackIds"
+ private const val KEY_SAVED_IDS = "androidx-nav-fragment:navigator:savedIds"
}
}
diff --git a/navigation/navigation-runtime-ktx/lint-baseline.xml b/navigation/navigation-runtime-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-runtime-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-runtime-truth/lint-baseline.xml b/navigation/navigation-runtime-truth/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-runtime-truth/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-runtime/lint-baseline.xml b/navigation/navigation-runtime/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-runtime/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-safe-args-generator/lint-baseline.xml b/navigation/navigation-safe-args-generator/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/navigation/navigation-safe-args-generator/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-safe-args-gradle-plugin/lint-baseline.xml b/navigation/navigation-safe-args-gradle-plugin/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/navigation/navigation-safe-args-gradle-plugin/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-testing/api/current.txt b/navigation/navigation-testing/api/current.txt
index b862bb3..8fc24e8 100644
--- a/navigation/navigation-testing/api/current.txt
+++ b/navigation/navigation-testing/api/current.txt
@@ -15,6 +15,7 @@
ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
ctor public TestNavigatorState(optional android.content.Context? context);
method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+ method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
}
}
diff --git a/navigation/navigation-testing/api/public_plus_experimental_current.txt b/navigation/navigation-testing/api/public_plus_experimental_current.txt
index b862bb3..8fc24e8 100644
--- a/navigation/navigation-testing/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-testing/api/public_plus_experimental_current.txt
@@ -15,6 +15,7 @@
ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
ctor public TestNavigatorState(optional android.content.Context? context);
method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+ method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
}
}
diff --git a/navigation/navigation-testing/api/restricted_current.txt b/navigation/navigation-testing/api/restricted_current.txt
index b862bb3..8fc24e8 100644
--- a/navigation/navigation-testing/api/restricted_current.txt
+++ b/navigation/navigation-testing/api/restricted_current.txt
@@ -15,6 +15,7 @@
ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
ctor public TestNavigatorState(optional android.content.Context? context);
method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+ method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
}
}
diff --git a/navigation/navigation-testing/lint-baseline.xml b/navigation/navigation-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt b/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
index a3de911..9140e76 100644
--- a/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
+++ b/navigation/navigation-testing/src/main/java/androidx/navigation/testing/TestNavigatorState.kt
@@ -64,6 +64,8 @@
}
}
+ private val savedStates = mutableMapOf<String, Bundle>()
+
override fun createBackStackEntry(
destination: NavDestination,
arguments: Bundle?
@@ -71,6 +73,23 @@
context, destination, arguments, lifecycleOwner, viewModelStoreProvider
)
+ /**
+ * Restore a previously saved [NavBackStackEntry]. You must have previously called
+ * [pop] with [previouslySavedEntry] and `true`.
+ */
+ public fun restoreBackStackEntry(previouslySavedEntry: NavBackStackEntry): NavBackStackEntry {
+ val savedState = checkNotNull(savedStates[previouslySavedEntry.id]) {
+ "restoreBackStackEntry(previouslySavedEntry) must be passed a NavBackStackEntry " +
+ "that was previously popped with popBackStack(previouslySavedEntry, true)"
+ }
+ return NavBackStackEntry.create(
+ context,
+ previouslySavedEntry.destination, previouslySavedEntry.arguments,
+ lifecycleOwner, viewModelStoreProvider,
+ previouslySavedEntry.id, savedState
+ )
+ }
+
override fun add(backStackEntry: NavBackStackEntry) {
super.add(backStackEntry)
updateMaxLifecycle()
@@ -80,10 +99,13 @@
val beforePopList = backStack.value
val poppedList = beforePopList.subList(beforePopList.indexOf(popUpTo), beforePopList.size)
super.pop(popUpTo, saveState)
- updateMaxLifecycle(poppedList)
+ updateMaxLifecycle(poppedList, saveState)
}
- private fun updateMaxLifecycle(poppedList: List<NavBackStackEntry> = emptyList()) {
+ private fun updateMaxLifecycle(
+ poppedList: List<NavBackStackEntry> = emptyList(),
+ saveState: Boolean = false
+ ) {
runBlocking(coroutineDispatcher) {
// NavBackStackEntry Lifecycles must be updated on the main thread
// as per the contract within Lifecycle, so we explicitly swap to the main thread
@@ -91,6 +113,13 @@
withContext(Dispatchers.Main.immediate) {
// Mark all removed NavBackStackEntries as DESTROYED
for (entry in poppedList.reversed()) {
+ if (saveState) {
+ // Move the NavBackStackEntry to the stopped state, then save its state
+ entry.maxLifecycle = Lifecycle.State.CREATED
+ val savedState = Bundle()
+ entry.saveState(savedState)
+ savedStates[entry.id] = savedState
+ }
entry.maxLifecycle = Lifecycle.State.DESTROYED
}
// Now go through the current list of destinations, updating their Lifecycle state
diff --git a/navigation/navigation-ui-ktx/lint-baseline.xml b/navigation/navigation-ui-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-ui-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-ui/build.gradle b/navigation/navigation-ui/build.gradle
index 446191d..ab64177 100644
--- a/navigation/navigation-ui/build.gradle
+++ b/navigation/navigation-ui/build.gradle
@@ -30,6 +30,9 @@
buildTypes.all {
consumerProguardFiles "proguard-rules.pro"
}
+ defaultConfig {
+ multiDexEnabled true
+ }
}
dependencies {
@@ -47,6 +50,7 @@
androidTestImplementation(ANDROIDX_TEST_CORE)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(TRUTH)
+ androidTestImplementation(MULTIDEX)
}
androidx {
diff --git a/navigation/navigation-ui/lint-baseline.xml b/navigation/navigation-ui/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/navigation/navigation-ui/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/navigation/navigation-ui/src/androidTest/AndroidManifest.xml b/navigation/navigation-ui/src/androidTest/AndroidManifest.xml
index 40d9eb7..ed9f9a9 100644
--- a/navigation/navigation-ui/src/androidTest/AndroidManifest.xml
+++ b/navigation/navigation-ui/src/androidTest/AndroidManifest.xml
@@ -15,6 +15,7 @@
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="androidx.navigation.ui">
+ package="androidx.navigation.ui"
+ android:name="androidx.multidex.MultiDexApplication">
</manifest>
diff --git a/paging/common/ktx/lint-baseline.xml b/paging/common/ktx/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/paging/common/ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/paging/guava/lint-baseline.xml b/paging/guava/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/paging/guava/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/paging/paging-compose/build.gradle b/paging/paging-compose/build.gradle
index a481bd4..669f393d3 100644
--- a/paging/paging-compose/build.gradle
+++ b/paging/paging-compose/build.gradle
@@ -32,7 +32,7 @@
implementation(libs.kotlinStdlib)
api(projectOrArtifact(":compose:foundation:foundation"))
- api(projectOrArtifact(":paging:paging-common"))
+ api("androidx.paging:paging-common:3.0.0")
androidTestImplementation(projectOrArtifact(":compose:ui:ui-test-junit4"))
androidTestImplementation(project(":compose:test-utils"))
diff --git a/paging/paging-compose/src/main/java/androidx/paging/compose/LazyPagingItems.kt b/paging/paging-compose/src/main/java/androidx/paging/compose/LazyPagingItems.kt
index 0df5445..7a4302d 100644
--- a/paging/paging-compose/src/main/java/androidx/paging/compose/LazyPagingItems.kt
+++ b/paging/paging-compose/src/main/java/androidx/paging/compose/LazyPagingItems.kt
@@ -48,10 +48,12 @@
* This instance can be used by the [items] and [itemsIndexed] methods inside [LazyListScope] to
* display data received from the [Flow] of [PagingData].
*
- * @param flow the [Flow] object which contains a stream of [PagingData] elements.
* @param T the type of value used by [PagingData].
*/
public class LazyPagingItems<T : Any> internal constructor(
+ /**
+ * the [Flow] object which contains a stream of [PagingData] elements.
+ */
private val flow: Flow<PagingData<T>>
) {
private val mainDispatcher = Dispatchers.Main
diff --git a/paging/runtime/ktx/lint-baseline.xml b/paging/runtime/ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/paging/runtime/ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/paging/rxjava2/ktx/lint-baseline.xml b/paging/rxjava2/ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/paging/rxjava2/ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/paging/rxjava2/lint-baseline.xml b/paging/rxjava2/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/paging/rxjava2/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/paging/rxjava3/lint-baseline.xml b/paging/rxjava3/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/paging/rxjava3/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/paging/samples/lint-baseline.xml b/paging/samples/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/paging/samples/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/palette/palette-ktx/lint-baseline.xml b/palette/palette-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/palette/palette-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/palette/palette/lint-baseline.xml b/palette/palette/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/palette/palette/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/preference/preference-ktx/lint-baseline.xml b/preference/preference-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/preference/preference-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/recyclerview/recyclerview-benchmark/lint-baseline.xml b/recyclerview/recyclerview-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/recyclerview/recyclerview-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/recyclerview/recyclerview-lint/lint-baseline.xml b/recyclerview/recyclerview-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/recyclerview/recyclerview-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/resourceinspection/resourceinspection-processor/lint-baseline.xml b/resourceinspection/resourceinspection-processor/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/resourceinspection/resourceinspection-processor/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/benchmark/lint-baseline.xml b/room/benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/room/benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/compiler-processing-testing/lint-baseline.xml b/room/compiler-processing-testing/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/room/compiler-processing-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/compiler-processing/lint-baseline.xml b/room/compiler-processing/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/room/compiler-processing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/compiler/lint-baseline.xml b/room/compiler/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/room/compiler/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/integration-tests/autovaluetestapp/lint-baseline.xml b/room/integration-tests/autovaluetestapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/room/integration-tests/autovaluetestapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/integration-tests/incremental-annotation-processing/lint-baseline.xml b/room/integration-tests/incremental-annotation-processing/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/room/integration-tests/incremental-annotation-processing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/integration-tests/kotlintestapp/lint-baseline.xml b/room/integration-tests/kotlintestapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/room/integration-tests/kotlintestapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/integration-tests/noappcompattestapp/lint-baseline.xml b/room/integration-tests/noappcompattestapp/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/room/integration-tests/noappcompattestapp/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/room/rxjava3/lint-baseline.xml b/room/rxjava3/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/room/rxjava3/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/savedstate/savedstate-ktx/lint-baseline.xml b/savedstate/savedstate-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/savedstate/savedstate-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/savedstate/savedstate/lint-baseline.xml b/savedstate/savedstate/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/savedstate/savedstate/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/security/identity-credential/lint-baseline.xml b/security/identity-credential/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/security/identity-credential/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/security/security-app-authenticator/lint-baseline.xml b/security/security-app-authenticator/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/security/security-app-authenticator/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/security/security-biometric/lint-baseline.xml b/security/security-biometric/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/security/security-biometric/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/security/security-crypto-ktx/lint-baseline.xml b/security/security-crypto-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/security/security-crypto-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/slices/benchmark/lint-baseline.xml b/slices/benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/slices/benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/slices/builders/ktx/lint-baseline.xml b/slices/builders/ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/slices/builders/ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/slices/remotecallback/lint-baseline.xml b/slices/remotecallback/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/slices/remotecallback/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/sqlite/sqlite-ktx/lint-baseline.xml b/sqlite/sqlite-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/sqlite/sqlite-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/startup/integration-tests/first-library/lint-baseline.xml b/startup/integration-tests/first-library/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/startup/integration-tests/first-library/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/startup/integration-tests/second-library/lint-baseline.xml b/startup/integration-tests/second-library/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/startup/integration-tests/second-library/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/startup/integration-tests/test-app/lint-baseline.xml b/startup/integration-tests/test-app/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/startup/integration-tests/test-app/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/startup/startup-runtime-lint/lint-baseline.xml b/startup/startup-runtime-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/startup/startup-runtime-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/startup/startup-runtime/lint-baseline.xml b/startup/startup-runtime/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/startup/startup-runtime/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/testutils/testutils-appcompat/lint-baseline.xml b/testutils/testutils-appcompat/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/testutils/testutils-appcompat/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/testutils/testutils-gradle-plugin/lint-baseline.xml b/testutils/testutils-gradle-plugin/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/testutils/testutils-gradle-plugin/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/testutils/testutils-mockito/lint-baseline.xml b/testutils/testutils-mockito/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/testutils/testutils-mockito/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/testutils/testutils-truth/lint-baseline.xml b/testutils/testutils-truth/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/testutils/testutils-truth/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/transition/transition-ktx/lint-baseline.xml b/transition/transition-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/transition/transition-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/vectordrawable/vectordrawable-seekable/lint-baseline.xml b/vectordrawable/vectordrawable-seekable/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/vectordrawable/vectordrawable-seekable/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/tiles/tiles/lint-baseline.xml b/wear/tiles/tiles/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/tiles/tiles/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-complications-provider/lint-baseline.xml b/wear/wear-complications-provider/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-complications-provider/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-complications-provider/samples/lint-baseline.xml b/wear/wear-complications-provider/samples/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-complications-provider/samples/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-input-testing/lint-baseline.xml b/wear/wear-input-testing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-input-testing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-input/lint-baseline.xml b/wear/wear-input/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-input/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-ongoing/lint-baseline.xml b/wear/wear-ongoing/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-ongoing/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-phone-interactions/lint-baseline.xml b/wear/wear-phone-interactions/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-phone-interactions/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-remote-interactions/lint-baseline.xml b/wear/wear-remote-interactions/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-remote-interactions/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface-client/lint-baseline.xml b/wear/wear-watchface-client/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-watchface-client/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/SerializationTest.kt b/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/SerializationTest.kt
index 0ce3355..d9f8180 100644
--- a/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/SerializationTest.kt
+++ b/wear/wear-watchface-client/src/androidTest/java/androidx/wear/watchface/client/test/SerializationTest.kt
@@ -56,7 +56,7 @@
private fun <T> loadGoldenResource(resourceId: Int, readFromParcel: (p: Parcel) -> T): T {
val resource = context.resources.openRawResource(resourceId)
- val bytes = Base64.getDecoder().decode(resource.readBytes())
+ val bytes = Base64.getDecoder().decode(String(resource.readBytes()))
val p = Parcel.obtain()
p.unmarshall(bytes, 0, bytes.size)
p.setDataPosition(0)
@@ -236,4 +236,11 @@
assertThat(complicationB.text.getTextAt(context.resources, 0)).isEqualTo("Example")
assertThat(complicationB.title!!.getTextAt(context.resources, 0)).isEqualTo("complication")
}
-}
\ No newline at end of file
+
+ @Test
+ public fun userStyleSchema() {
+ // TODO(b/187498135): Implement a golden test. This is harder than it sounds because the raw
+ // bytes of a serialized Parcel is not portable and can differ between architectures even
+ // on the same API level. The tests above possibly only pass on current bots by luck.
+ }
+}
diff --git a/wear/wear-watchface-complications-rendering/api/current.txt b/wear/wear-watchface-complications-rendering/api/current.txt
index 085dab4..2093fe8 100644
--- a/wear/wear-watchface-complications-rendering/api/current.txt
+++ b/wear/wear-watchface-complications-rendering/api/current.txt
@@ -20,15 +20,15 @@
public final class ComplicationDrawable extends android.graphics.drawable.Drawable {
ctor public ComplicationDrawable();
- ctor public ComplicationDrawable(android.content.Context);
- ctor public ComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable);
- method public void draw(android.graphics.Canvas);
+ ctor public ComplicationDrawable(android.content.Context context);
+ ctor public ComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable);
+ method public void draw(android.graphics.Canvas canvas);
method public androidx.wear.watchface.complications.rendering.ComplicationStyle getActiveStyle();
method public androidx.wear.watchface.complications.rendering.ComplicationStyle getAmbientStyle();
method public androidx.wear.complications.data.ComplicationData? getComplicationData();
method public android.content.Context? getContext();
method public long getCurrentTimeMillis();
- method public static androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context, int);
+ method public static androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context context, int id);
method public long getHighlightDuration();
method public CharSequence? getNoDataText();
method @Deprecated public int getOpacity();
@@ -37,19 +37,36 @@
method public boolean isInAmbientMode();
method public boolean isLowBitAmbient();
method public boolean isRangedValueProgressHidden();
- method public boolean onTap(@Px int, @Px int);
- method public void setAlpha(int);
- method public void setBurnInProtection(boolean);
- method public void setColorFilter(android.graphics.ColorFilter?);
- method public void setComplicationData(androidx.wear.complications.data.ComplicationData?, boolean);
- method public void setContext(android.content.Context);
- method public void setCurrentTimeMillis(long);
- method public void setHighlightDuration(@IntRange(from=0) long);
- method public void setHighlighted(boolean);
- method public void setInAmbientMode(boolean);
- method public void setLowBitAmbient(boolean);
- method public void setNoDataText(CharSequence?);
- method public void setRangedValueProgressHidden(boolean);
+ method public boolean onTap(@Px int x, @Px int y);
+ method public void setAlpha(@IntRange(from=0, to=255) int alpha);
+ method public void setBurnInProtectionOn(boolean p);
+ method public void setColorFilter(android.graphics.ColorFilter? colorFilter);
+ method public void setComplicationData(androidx.wear.complications.data.ComplicationData? complicationData, boolean loadDrawablesAsync);
+ method public void setContext(android.content.Context context);
+ method public void setCurrentTimeMillis(long p);
+ method public void setHighlightDuration(@IntRange(from=0) long highlightDurationMillis);
+ method public void setHighlighted(boolean p);
+ method public void setInAmbientMode(boolean p);
+ method public void setLowBitAmbient(boolean p);
+ method public void setNoDataText(CharSequence? noDataText);
+ method public void setRangedValueProgressHidden(boolean rangedValueProgressHidden);
+ property public final androidx.wear.watchface.complications.rendering.ComplicationStyle activeStyle;
+ property public final androidx.wear.watchface.complications.rendering.ComplicationStyle ambientStyle;
+ property public final androidx.wear.complications.data.ComplicationData? complicationData;
+ property public final android.content.Context? context;
+ property public final long currentTimeMillis;
+ property public final long highlightDuration;
+ property public final boolean isBurnInProtectionOn;
+ property public final boolean isHighlighted;
+ property public final boolean isInAmbientMode;
+ property public final boolean isLowBitAmbient;
+ property public final boolean isRangedValueProgressHidden;
+ property public final CharSequence? noDataText;
+ field public static final androidx.wear.watchface.complications.rendering.ComplicationDrawable.Companion Companion;
+ }
+
+ public static final class ComplicationDrawable.Companion {
+ method public androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context context, int id);
}
public final class ComplicationHighlightRenderer {
diff --git a/wear/wear-watchface-complications-rendering/api/public_plus_experimental_current.txt b/wear/wear-watchface-complications-rendering/api/public_plus_experimental_current.txt
index 085dab4..2093fe8 100644
--- a/wear/wear-watchface-complications-rendering/api/public_plus_experimental_current.txt
+++ b/wear/wear-watchface-complications-rendering/api/public_plus_experimental_current.txt
@@ -20,15 +20,15 @@
public final class ComplicationDrawable extends android.graphics.drawable.Drawable {
ctor public ComplicationDrawable();
- ctor public ComplicationDrawable(android.content.Context);
- ctor public ComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable);
- method public void draw(android.graphics.Canvas);
+ ctor public ComplicationDrawable(android.content.Context context);
+ ctor public ComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable);
+ method public void draw(android.graphics.Canvas canvas);
method public androidx.wear.watchface.complications.rendering.ComplicationStyle getActiveStyle();
method public androidx.wear.watchface.complications.rendering.ComplicationStyle getAmbientStyle();
method public androidx.wear.complications.data.ComplicationData? getComplicationData();
method public android.content.Context? getContext();
method public long getCurrentTimeMillis();
- method public static androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context, int);
+ method public static androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context context, int id);
method public long getHighlightDuration();
method public CharSequence? getNoDataText();
method @Deprecated public int getOpacity();
@@ -37,19 +37,36 @@
method public boolean isInAmbientMode();
method public boolean isLowBitAmbient();
method public boolean isRangedValueProgressHidden();
- method public boolean onTap(@Px int, @Px int);
- method public void setAlpha(int);
- method public void setBurnInProtection(boolean);
- method public void setColorFilter(android.graphics.ColorFilter?);
- method public void setComplicationData(androidx.wear.complications.data.ComplicationData?, boolean);
- method public void setContext(android.content.Context);
- method public void setCurrentTimeMillis(long);
- method public void setHighlightDuration(@IntRange(from=0) long);
- method public void setHighlighted(boolean);
- method public void setInAmbientMode(boolean);
- method public void setLowBitAmbient(boolean);
- method public void setNoDataText(CharSequence?);
- method public void setRangedValueProgressHidden(boolean);
+ method public boolean onTap(@Px int x, @Px int y);
+ method public void setAlpha(@IntRange(from=0, to=255) int alpha);
+ method public void setBurnInProtectionOn(boolean p);
+ method public void setColorFilter(android.graphics.ColorFilter? colorFilter);
+ method public void setComplicationData(androidx.wear.complications.data.ComplicationData? complicationData, boolean loadDrawablesAsync);
+ method public void setContext(android.content.Context context);
+ method public void setCurrentTimeMillis(long p);
+ method public void setHighlightDuration(@IntRange(from=0) long highlightDurationMillis);
+ method public void setHighlighted(boolean p);
+ method public void setInAmbientMode(boolean p);
+ method public void setLowBitAmbient(boolean p);
+ method public void setNoDataText(CharSequence? noDataText);
+ method public void setRangedValueProgressHidden(boolean rangedValueProgressHidden);
+ property public final androidx.wear.watchface.complications.rendering.ComplicationStyle activeStyle;
+ property public final androidx.wear.watchface.complications.rendering.ComplicationStyle ambientStyle;
+ property public final androidx.wear.complications.data.ComplicationData? complicationData;
+ property public final android.content.Context? context;
+ property public final long currentTimeMillis;
+ property public final long highlightDuration;
+ property public final boolean isBurnInProtectionOn;
+ property public final boolean isHighlighted;
+ property public final boolean isInAmbientMode;
+ property public final boolean isLowBitAmbient;
+ property public final boolean isRangedValueProgressHidden;
+ property public final CharSequence? noDataText;
+ field public static final androidx.wear.watchface.complications.rendering.ComplicationDrawable.Companion Companion;
+ }
+
+ public static final class ComplicationDrawable.Companion {
+ method public androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context context, int id);
}
public final class ComplicationHighlightRenderer {
diff --git a/wear/wear-watchface-complications-rendering/api/restricted_current.txt b/wear/wear-watchface-complications-rendering/api/restricted_current.txt
index 110cc54..8b9e974 100644
--- a/wear/wear-watchface-complications-rendering/api/restricted_current.txt
+++ b/wear/wear-watchface-complications-rendering/api/restricted_current.txt
@@ -20,15 +20,15 @@
public final class ComplicationDrawable extends android.graphics.drawable.Drawable {
ctor public ComplicationDrawable();
- ctor public ComplicationDrawable(android.content.Context);
- ctor public ComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable);
- method public void draw(android.graphics.Canvas);
+ ctor public ComplicationDrawable(android.content.Context context);
+ ctor public ComplicationDrawable(androidx.wear.watchface.complications.rendering.ComplicationDrawable drawable);
+ method public void draw(android.graphics.Canvas canvas);
method public androidx.wear.watchface.complications.rendering.ComplicationStyle getActiveStyle();
method public androidx.wear.watchface.complications.rendering.ComplicationStyle getAmbientStyle();
method public androidx.wear.complications.data.ComplicationData? getComplicationData();
method public android.content.Context? getContext();
method public long getCurrentTimeMillis();
- method public static androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context, int);
+ method public static androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context context, int id);
method public long getHighlightDuration();
method public CharSequence? getNoDataText();
method @Deprecated public int getOpacity();
@@ -37,19 +37,36 @@
method public boolean isInAmbientMode();
method public boolean isLowBitAmbient();
method public boolean isRangedValueProgressHidden();
- method public boolean onTap(@Px int, @Px int);
- method public void setAlpha(int);
- method public void setBurnInProtection(boolean);
- method public void setColorFilter(android.graphics.ColorFilter?);
- method public void setComplicationData(androidx.wear.complications.data.ComplicationData?, boolean);
- method public void setContext(android.content.Context);
- method public void setCurrentTimeMillis(long);
- method public void setHighlightDuration(@IntRange(from=0) long);
- method public void setHighlighted(boolean);
- method public void setInAmbientMode(boolean);
- method public void setLowBitAmbient(boolean);
- method public void setNoDataText(CharSequence?);
- method public void setRangedValueProgressHidden(boolean);
+ method public boolean onTap(@Px int x, @Px int y);
+ method public void setAlpha(@IntRange(from=0, to=255) int alpha);
+ method public void setBurnInProtectionOn(boolean p);
+ method public void setColorFilter(android.graphics.ColorFilter? colorFilter);
+ method public void setComplicationData(androidx.wear.complications.data.ComplicationData? complicationData, boolean loadDrawablesAsync);
+ method public void setContext(android.content.Context context);
+ method public void setCurrentTimeMillis(long p);
+ method public void setHighlightDuration(@IntRange(from=0) long highlightDurationMillis);
+ method public void setHighlighted(boolean p);
+ method public void setInAmbientMode(boolean p);
+ method public void setLowBitAmbient(boolean p);
+ method public void setNoDataText(CharSequence? noDataText);
+ method public void setRangedValueProgressHidden(boolean rangedValueProgressHidden);
+ property public final androidx.wear.watchface.complications.rendering.ComplicationStyle activeStyle;
+ property public final androidx.wear.watchface.complications.rendering.ComplicationStyle ambientStyle;
+ property public final androidx.wear.complications.data.ComplicationData? complicationData;
+ property public final android.content.Context? context;
+ property public final long currentTimeMillis;
+ property public final long highlightDuration;
+ property public final boolean isBurnInProtectionOn;
+ property public final boolean isHighlighted;
+ property public final boolean isInAmbientMode;
+ property public final boolean isLowBitAmbient;
+ property public final boolean isRangedValueProgressHidden;
+ property public final CharSequence? noDataText;
+ field public static final androidx.wear.watchface.complications.rendering.ComplicationDrawable.Companion Companion;
+ }
+
+ public static final class ComplicationDrawable.Companion {
+ method public androidx.wear.watchface.complications.rendering.ComplicationDrawable? getDrawable(android.content.Context context, int id);
}
public final class ComplicationHighlightRenderer {
diff --git a/wear/wear-watchface-complications-rendering/lint-baseline.xml b/wear/wear-watchface-complications-rendering/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-watchface-complications-rendering/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/CanvasComplicationDrawable.kt b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/CanvasComplicationDrawable.kt
index 05df52f..9222881 100644
--- a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/CanvasComplicationDrawable.kt
+++ b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/CanvasComplicationDrawable.kt
@@ -92,7 +92,7 @@
field = value
value.isInAmbientMode = watchState.isAmbient.value
value.isLowBitAmbient = watchState.hasLowBitAmbient
- value.setBurnInProtection(watchState.hasBurnInProtection)
+ value.isBurnInProtectionOn = watchState.hasBurnInProtection
attachedComplication?.scheduleUpdateComplications()
}
diff --git a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.java b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.java
deleted file mode 100644
index 55c1e16..0000000
--- a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.java
+++ /dev/null
@@ -1,870 +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.wear.watchface.complications.rendering;
-
-import android.app.PendingIntent.CanceledException;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Looper;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Xml;
-
-import androidx.annotation.IntRange;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.Px;
-import androidx.annotation.VisibleForTesting;
-import androidx.wear.complications.ComplicationHelperActivity;
-import androidx.wear.complications.data.ComplicationData;
-import androidx.wear.complications.data.ComplicationType;
-import androidx.wear.complications.data.DataKt;
-import androidx.wear.watchface.complications.rendering.ComplicationRenderer.OnInvalidateListener;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * A styleable drawable object that draws complications. You can create a ComplicationDrawable from
- * XML inflation or by using one of the constructor methods.
- *
- * <h3>Constructing a ComplicationDrawable</h3>
- *
- * <p>To construct a ComplicationDrawable programmatically, use the {@link
- * #ComplicationDrawable(Context)} constructor. Afterwards, styling attributes you want to modify
- * can be set via set methods.
- *
- * <pre>
- * public void onCreate(SurfaceHolder holder) {
- * ...
- * ComplicationDrawable complicationDrawable = new ComplicationDrawable(WatchFaceService.this);
- * complicationDrawable.setBackgroundColorActive(backgroundColor);
- * complicationDrawable.setTextColorActive(textColor);
- * ...
- * }</pre>
- *
- * <h3>Constructing a ComplicationDrawable from XML</h3>
- *
- * <p>Constructing a ComplicationDrawable from an XML file makes it easier to modify multiple
- * styling attributes at once without calling any set methods. You may also use different XML files
- * to switch between different styles your watch face supports.
- *
- * <p>To construct a ComplicationDrawable from a drawable XML file, you may create an XML file in
- * your project's {@code res/drawable} folder. A ComplicationDrawable with red text and white title
- * in active mode, and white text and white title in ambient mode would look like this:
- *
- * <pre>
- * <?xml version="1.0" encoding="utf-8"?>
- * <android.support.wearable.complications.rendering.ComplicationDrawable
- * xmlns:app="http://schemas.android.com/apk/res-auto"
- * app:textColor="#FFFF0000"
- * app:titleColor="#FFFFFFFF">
- * <ambient
- * app:textColor="#FFFFFFFF" />
- * </android.support.wearable.complications.rendering.ComplicationDrawable>
- * </pre>
- *
- * <p>A top-level {@code drawable} tag with the {@code class} attribute may also be used to
- * construct a ComplicationDrawable from an XML file:
- *
- * <pre>
- * <?xml version="1.0" encoding="utf-8"?>
- * <drawable
- * class="android.support.wearable.complications.rendering.ComplicationDrawable"
- * xmlns:app="http://schemas.android.com/apk/res-auto"
- * app:textColor="#FFFF0000"
- * app:titleColor="#FFFFFFFF">
- * <ambient
- * app:textColor="#FFFFFFFF" />
- * </drawable></pre>
- *
- * <p>To inflate a ComplicationDrawable from XML file, use the {@link #getDrawable(Context, int)}
- * method. ComplicationDrawable needs access to the current context in order to style and draw
- * the complication.
- *
- * <pre>
- * public void onCreate(SurfaceHolder holder) {
- * ...
- * ComplicationDrawable complicationDrawable = (ComplicationDrawable)
- * getDrawable(R.drawable.complication);
- * complicationDrawable.setContext(WatchFaceService.this);
- * ...
- * }</pre>
- *
- * <h4>Syntax:</h4>
- *
- * <pre>
- * <?xml version="1.0" encoding="utf-8"?>
- * <android.support.wearable.complications.rendering.ComplicationDrawable
- * xmlns:app="http://schemas.android.com/apk/res-auto"
- * app:backgroundColor="color"
- * app:backgroundDrawable="drawable"
- * app:borderColor="color"
- * app:borderDashGap="dimension"
- * app:borderDashWidth="dimension"
- * app:borderRadius="dimension"
- * app:borderStyle="none|solid|dashed"
- * app:borderWidth="dimension"
- * app:highlightColor="color"
- * app:iconColor="color"
- * app:rangedValuePrimaryColor="color"
- * app:rangedValueProgressHidden="boolean"
- * app:rangedValueRingWidth="dimension"
- * app:rangedValueSecondaryColor="color"
- * app:textColor="color"
- * app:textSize="dimension"
- * app:textTypeface="string"
- * app:titleColor="color"
- * app:titleSize="dimension"
- * app:titleTypeface="string">
- * <ambient
- * app:backgroundColor="color"
- * app:backgroundDrawable="drawable"
- * app:borderColor="color"
- * app:borderDashGap="dimension"
- * app:borderDashWidth="dimension"
- * app:borderRadius="dimension"
- * app:borderStyle="none|solid|dashed"
- * app:borderWidth="dimension"
- * app:highlightColor="color"
- * app:iconColor="color"
- * app:rangedValuePrimaryColor="color"
- * app:rangedValueRingWidth="dimension"
- * app:rangedValueSecondaryColor="color"
- * app:textColor="color"
- * app:textSize="dimension"
- * app:textTypeface="string"
- * app:titleColor="color"
- * app:titleSize="dimension"
- * app:titleTypeface="string" />
- * </android.support.wearable.complications.rendering.ComplicationDrawable>
- * </pre>
- *
- * <p>Attributes of the top-level tag apply to both active and ambient modes while attributes of the
- * inner {@code ambient} tag only apply to ambient mode. As an exception, top-level only {@code
- * rangedValueProgressHidden} attribute applies to both modes, and cannot be overridden in ambient
- * mode. To hide ranged value in only one of the active or ambient modes, you may consider setting
- * {@code rangedValuePrimaryColor} and {@code rangedValueSecondaryColor} to {@link
- * android.graphics.Color#TRANSPARENT} instead.
- *
- * <h3>Drawing a ComplicationDrawable</h3>
- *
- * <p>Depending on the size and shape of the bounds, the layout of the complication may change. For
- * instance, a short text complication with an icon that is drawn on square bounds would draw the
- * icon above the short text, but a short text complication with an icon that is drawn on wide
- * rectangular bounds might draw the icon to the left of the short text instead.
- */
-public final class ComplicationDrawable extends Drawable {
-
- private Context mContext;
- private ComplicationRenderer mComplicationRenderer;
-
- private final ComplicationStyle mActiveStyle;
- private final ComplicationStyle mAmbientStyle;
-
- private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
-
- private final Runnable mUnhighlightRunnable =
- () -> {
- setHighlighted(false);
- invalidateSelf();
- };
-
- private final OnInvalidateListener mRendererInvalidateListener = () -> invalidateSelf();
-
- private CharSequence mNoDataText;
- private long mHighlightDuration;
- private long mCurrentTimeMillis;
- private boolean mInAmbientMode;
- private boolean mLowBitAmbient;
- private boolean mBurnInProtection;
- private boolean mHighlighted;
- private boolean mRangedValueProgressHidden;
-
- private boolean mIsInflatedFromXml;
- private boolean mAlreadyStyled;
-
- /** Default constructor. */
- public ComplicationDrawable() {
- mActiveStyle = new ComplicationStyle();
- mAmbientStyle = new ComplicationStyle();
- }
-
- /**
- * Creates a ComplicationDrawable using the given context. If this constructor is used, calling
- * {@link #setContext(Context)} may not be necessary.
- */
- public ComplicationDrawable(@NonNull Context context) {
- this();
- setContext(context);
- }
-
- public ComplicationDrawable(@NonNull ComplicationDrawable drawable) {
- mActiveStyle = new ComplicationStyle(drawable.mActiveStyle);
- mAmbientStyle = new ComplicationStyle(drawable.mAmbientStyle);
- mNoDataText = drawable.mNoDataText.subSequence(0, drawable.mNoDataText.length());
- mHighlightDuration = drawable.mHighlightDuration;
- mCurrentTimeMillis = drawable.mCurrentTimeMillis;
- setBounds(drawable.getBounds());
-
- mInAmbientMode = drawable.mInAmbientMode;
- mLowBitAmbient = drawable.mLowBitAmbient;
- mBurnInProtection = drawable.mBurnInProtection;
- mHighlighted = false;
- mRangedValueProgressHidden = drawable.mRangedValueProgressHidden;
- mIsInflatedFromXml = drawable.mIsInflatedFromXml;
- mAlreadyStyled = true;
- }
-
- /**
- * Creates a ComplicationDrawable from a resource.
- *
- * @param context The {@link Context} to load the resource from
- * @param id The id of the resource to load
- * @return The {@link ComplicationDrawable} loaded from the specified resource id or null if it
- * doesn't exist.
- */
- @Nullable
- public static ComplicationDrawable getDrawable(@NonNull Context context, int id) {
- if (context == null) {
- throw new IllegalArgumentException("Argument \"context\" should not be null.");
- }
- ComplicationDrawable drawable = (ComplicationDrawable) context.getDrawable(id);
- if (drawable == null) {
- return null;
- }
-
- drawable.setContext(context);
- return drawable;
- }
-
- /** Sets the style to default values using resources. */
- private static void setStyleToDefaultValues(ComplicationStyle style, Resources r) {
- style.setBackgroundColor(
- r.getColor(R.color.complicationDrawable_backgroundColor, null));
- style.setTextColor(r.getColor(R.color.complicationDrawable_textColor, null));
- style.setTitleColor(r.getColor(R.color.complicationDrawable_titleColor, null));
- style.setTextTypeface(
- Typeface.create(
- r.getString(R.string.complicationDrawable_textTypeface), Typeface.NORMAL));
- style.setTitleTypeface(
- Typeface.create(
- r.getString(R.string.complicationDrawable_titleTypeface), Typeface.NORMAL));
- style.setTextSize(r.getDimensionPixelSize(R.dimen.complicationDrawable_textSize));
- style.setTitleSize(r.getDimensionPixelSize(R.dimen.complicationDrawable_titleSize));
- style.setIconColor(r.getColor(R.color.complicationDrawable_iconColor, null));
- style.setBorderColor(r.getColor(R.color.complicationDrawable_borderColor, null));
- style.setBorderWidth(r.getDimensionPixelSize(R.dimen.complicationDrawable_borderWidth));
- style.setBorderRadius(r.getDimensionPixelSize(R.dimen.complicationDrawable_borderRadius));
- style.setBorderStyle(r.getInteger(R.integer.complicationDrawable_borderStyle));
- style.setBorderDashWidth(
- r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashWidth));
- style.setBorderDashGap(r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashGap));
- style.setRangedValueRingWidth(
- r.getDimensionPixelSize(R.dimen.complicationDrawable_rangedValueRingWidth));
- style.setRangedValuePrimaryColor(
- r.getColor(R.color.complicationDrawable_rangedValuePrimaryColor, null));
- style.setRangedValueSecondaryColor(
- r.getColor(R.color.complicationDrawable_rangedValueSecondaryColor, null));
- style.setHighlightColor(r.getColor(R.color.complicationDrawable_highlightColor, null));
- }
-
- /**
- * Sets the context used to render the complication. If a context is not set,
- * ComplicationDrawable will throw an {@link IllegalStateException} if one of
- * {@link #draw(Canvas)}, {@link #setBounds(Rect)}, or {@link
- * #setComplicationData(ComplicationData, boolean)} is called.
- *
- * <p>While this can be called from any context, ideally, a
- * androidx.wear.watchface.WatchFaceService object should be passed here to allow creating
- * permission dialogs by the {@link #onTap(int, int)} method, in case current watch face
- * doesn't have the permission to receive complication data.
- *
- * <p>If this ComplicationDrawable is retrieved using {@link Resources#getDrawable(int, Theme)},
- * this method must be called before calling any of the methods mentioned above.
- *
- * <p>If this ComplicationDrawable is not inflated from an XML file, this method will reset the
- * style to match the default values, so if {@link #ComplicationDrawable()} is used to construct
- * a ComplicationDrawable, this method should be called right after.
- */
- public void setContext(@NonNull Context context) {
- if (context == null) {
- throw new IllegalArgumentException("Argument \"context\" should not be null.");
- }
- if (Objects.equals(context, mContext)) {
- return;
- }
- mContext = context;
-
- if (!mIsInflatedFromXml && !mAlreadyStyled) {
- setStyleToDefaultValues(mActiveStyle, context.getResources());
- setStyleToDefaultValues(mAmbientStyle, context.getResources());
- }
-
- if (!mAlreadyStyled) {
- mHighlightDuration = context.getResources()
- .getInteger(R.integer.complicationDrawable_highlightDurationMs);
- }
-
- mComplicationRenderer = new ComplicationRenderer(mContext, mActiveStyle, mAmbientStyle);
- mComplicationRenderer.setOnInvalidateListener(mRendererInvalidateListener);
- if (mNoDataText == null) {
- setNoDataText(context.getString(R.string.complicationDrawable_noDataText));
- } else {
- mComplicationRenderer.setNoDataText(mNoDataText);
- }
- mComplicationRenderer.setRangedValueProgressHidden(mRangedValueProgressHidden);
- mComplicationRenderer.setBounds(getBounds());
- }
-
- /**
- * Returns the {@link Context} used to render the complication.
- */
- @Nullable public Context getContext() {
- return mContext;
- }
-
- private void inflateAttributes(Resources r, XmlPullParser parser) {
- TypedArray a =
- r.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.ComplicationDrawable);
- setRangedValueProgressHidden(
- a.getBoolean(R.styleable.ComplicationDrawable_rangedValueProgressHidden, false));
- a.recycle();
- }
-
- private void inflateStyle(boolean isAmbient, Resources r, XmlPullParser parser) {
- TypedArray a =
- r.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.ComplicationDrawable);
- ComplicationStyle complicationStyle = isAmbient ? mAmbientStyle : mActiveStyle;
- if (a.hasValue(R.styleable.ComplicationDrawable_backgroundColor)) {
- complicationStyle.setBackgroundColor(
- a.getColor(
- R.styleable.ComplicationDrawable_backgroundColor,
- r.getColor(R.color.complicationDrawable_backgroundColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_backgroundDrawable)) {
- complicationStyle.setBackgroundDrawable(
- a.getDrawable(R.styleable.ComplicationDrawable_backgroundDrawable));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_textColor)) {
- complicationStyle.setTextColor(
- a.getColor(
- R.styleable.ComplicationDrawable_textColor,
- r.getColor(R.color.complicationDrawable_textColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_titleColor)) {
- complicationStyle.setTitleColor(
- a.getColor(
- R.styleable.ComplicationDrawable_titleColor,
- r.getColor(R.color.complicationDrawable_titleColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_textTypeface)) {
- complicationStyle.setTextTypeface(
- Typeface.create(
- a.getString(R.styleable.ComplicationDrawable_textTypeface),
- Typeface.NORMAL));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_titleTypeface)) {
- complicationStyle.setTitleTypeface(
- Typeface.create(
- a.getString(R.styleable.ComplicationDrawable_titleTypeface),
- Typeface.NORMAL));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_textSize)) {
- complicationStyle.setTextSize(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_textSize,
- r.getDimensionPixelSize(R.dimen.complicationDrawable_textSize)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_titleSize)) {
- complicationStyle.setTitleSize(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_titleSize,
- r.getDimensionPixelSize(R.dimen.complicationDrawable_titleSize)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_iconColor)) {
- complicationStyle.setIconColor(
- a.getColor(
- R.styleable.ComplicationDrawable_iconColor,
- r.getColor(R.color.complicationDrawable_iconColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_borderColor)) {
- complicationStyle.setBorderColor(
- a.getColor(
- R.styleable.ComplicationDrawable_borderColor,
- r.getColor(R.color.complicationDrawable_borderColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_borderRadius)) {
- complicationStyle.setBorderRadius(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_borderRadius,
- r.getDimensionPixelSize(R.dimen.complicationDrawable_borderRadius)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_borderStyle)) {
- complicationStyle.setBorderStyle(
- a.getInt(
- R.styleable.ComplicationDrawable_borderStyle,
- r.getInteger(R.integer.complicationDrawable_borderStyle)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_borderDashWidth)) {
- complicationStyle.setBorderDashWidth(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_borderDashWidth,
- r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashWidth)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_borderDashGap)) {
- complicationStyle.setBorderDashGap(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_borderDashGap,
- r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashGap)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_borderWidth)) {
- complicationStyle.setBorderWidth(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_borderWidth,
- r.getDimensionPixelSize(R.dimen.complicationDrawable_borderWidth)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_rangedValueRingWidth)) {
- complicationStyle.setRangedValueRingWidth(
- a.getDimensionPixelSize(
- R.styleable.ComplicationDrawable_rangedValueRingWidth,
- r.getDimensionPixelSize(
- R.dimen.complicationDrawable_rangedValueRingWidth)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_rangedValuePrimaryColor)) {
- complicationStyle.setRangedValuePrimaryColor(
- a.getColor(
- R.styleable.ComplicationDrawable_rangedValuePrimaryColor,
- r.getColor(
- R.color.complicationDrawable_rangedValuePrimaryColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_rangedValueSecondaryColor)) {
- complicationStyle.setRangedValueSecondaryColor(
- a.getColor(
- R.styleable.ComplicationDrawable_rangedValueSecondaryColor,
- r.getColor(
- R.color.complicationDrawable_rangedValueSecondaryColor, null)));
- }
- if (a.hasValue(R.styleable.ComplicationDrawable_highlightColor)) {
- complicationStyle.setHighlightColor(
- a.getColor(
- R.styleable.ComplicationDrawable_highlightColor,
- r.getColor(R.color.complicationDrawable_highlightColor, null)));
- }
- a.recycle();
- }
-
- /**
- * Inflates this ComplicationDrawable from an XML resource. This can't be called more than once
- * for each ComplicationDrawable. Note that framework may have called this once to create the
- * ComplicationDrawable instance from an XML resource.
- *
- * @param r Resources used to resolve attribute values
- * @param parser XML parser from which to inflate this ComplicationDrawable
- * @param attrs Base set of attribute values
- * @param theme Ignored by ComplicationDrawable
- */
- @Override
- @SuppressWarnings("ObjectToString")
- public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
- @NonNull AttributeSet attrs, @Nullable Theme theme)
- throws XmlPullParserException, IOException {
- if (mIsInflatedFromXml) {
- throw new IllegalStateException("inflate may be called once only.");
- }
- mIsInflatedFromXml = true;
- int type;
- final int outerDepth = parser.getDepth();
- // Inflate attributes always shared between active and ambient mode
- inflateAttributes(r, parser);
- // Reset both style builders to default values
- setStyleToDefaultValues(mActiveStyle, r);
- setStyleToDefaultValues(mAmbientStyle, r);
- // Attributes of the outer tag applies to both active and ambient styles
- inflateStyle(false, r, parser);
- inflateStyle(true, r, parser);
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- // Attributes of inner <ambient> tag applies to ambient style only
- final String name = parser.getName();
- if (TextUtils.equals(name, "ambient")) {
- inflateStyle(true, r, parser);
- } else {
- Log.w(
- "ComplicationDrawable",
- "Unknown element: " + name + " for ComplicationDrawable " + this);
- }
- }
- }
-
- /**
- * Draws the complication for the last known time. Last known time is derived from
- * ComplicationDrawable#setCurrentTimeMillis(long)}.
- *
- * @param canvas Canvas for the complication to be drawn onto
- */
- @Override
- public void draw(@NonNull Canvas canvas) {
- assertInitialized();
- updateStyleIfRequired();
- mComplicationRenderer.draw(
- canvas,
- mCurrentTimeMillis,
- mInAmbientMode,
- mLowBitAmbient,
- mBurnInProtection,
- mHighlighted);
- }
-
- /** Does nothing. */
- @Override
- public void setAlpha(int alpha) {
- // No op.
- }
-
- // TODO(b/186499115): In follow up patch, when this class is converted to Kotlin, make link
- // working.
- /**
- * Does nothing. Use {link ComplicationStyle#setImageColorFilter(ColorFilter)} instead to apply
- * color filter to small and large images.
- */
- @Override
- public void setColorFilter(@Nullable ColorFilter colorFilter) {
- // No op.
- }
-
- /**
- * {@inheritDoc}
- *
- * @deprecated This method is no longer used in graphics optimizations
- */
- @Override
- @Deprecated
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- protected void onBoundsChange(@NonNull Rect bounds) {
- if (mComplicationRenderer != null) {
- mComplicationRenderer.setBounds(bounds);
- }
- }
-
- /**
- * Sets the text to be rendered when {@link ComplicationData} is of type {@link
- * ComplicationType#NO_DATA}. If {@code noDataText} is null, an empty text will be
- * rendered.
- */
- public void setNoDataText(@Nullable CharSequence noDataText) {
- if (noDataText == null) {
- mNoDataText = "";
- } else {
- mNoDataText = noDataText.subSequence(0, noDataText.length());
- }
- if (mComplicationRenderer != null) {
- mComplicationRenderer.setNoDataText(mNoDataText);
- }
- }
-
- /**
- * Sets if the ranged value progress should be hidden when {@link ComplicationData} is of type
- * {@link ComplicationType#RANGED_VALUE}.
- *
- * @param rangedValueProgressHidden {@code true} if progress should be hidden, {@code false}
- * otherwise
- * @attr ref androidx.wear.watchface.complications.rendering.R
- * .styleable#ComplicationDrawable_rangedValueProgressHidden
- */
- public void setRangedValueProgressHidden(boolean rangedValueProgressHidden) {
- mRangedValueProgressHidden = rangedValueProgressHidden;
- if (mComplicationRenderer != null) {
- mComplicationRenderer.setRangedValueProgressHidden(rangedValueProgressHidden);
- }
- }
-
- /** Returns {@code true} if the ranged value progress is hidden, {@code false} otherwise. */
- public boolean isRangedValueProgressHidden() {
- return mRangedValueProgressHidden;
- }
-
- /**
- * Sets the complication data to be drawn. If {@code complicationData} is {@code null}, nothing
- * will be drawn when {@link #draw(Canvas)} is called.
- *
- * @param complicationData The [ComplicationData] to set
- * @param loadDrawablesAsync If true any drawables should be loaded asynchronously,
- * otherwise they will be loaded synchronously.
- */
- public void setComplicationData(
- @Nullable ComplicationData complicationData,
- boolean loadDrawablesAsync
- ) {
- assertInitialized();
- mComplicationRenderer.setComplicationData(
- complicationData != null ? complicationData.asWireComplicationData() : null,
- loadDrawablesAsync
- );
- }
-
- /**
- * Returns the {@link ComplicationData} to be drawn by this ComplicationDrawable.
- */
- @Nullable
- public ComplicationData getComplicationData() {
- return (mComplicationRenderer.getComplicationData() != null)
- ? DataKt.toApiComplicationData(mComplicationRenderer.getComplicationData()) : null;
- }
-
- /** Sets whether the complication should be rendered in ambient mode. */
- public void setInAmbientMode(boolean inAmbientMode) {
- mInAmbientMode = inAmbientMode;
- }
-
- /** Returns whether the complication is rendered in ambient mode. */
- public boolean isInAmbientMode() {
- return mInAmbientMode;
- }
-
- /**
- * Sets whether the complication, when rendering in ambient mode, should apply a style suitable
- * for low bit ambient mode.
- */
- public void setLowBitAmbient(boolean lowBitAmbient) {
- mLowBitAmbient = lowBitAmbient;
- }
-
- /**
- * Returns whether the complication, when rendering in ambient mode, should apply a style
- * suitable for low bit ambient mode.
- */
- public boolean isLowBitAmbient() {
- return mLowBitAmbient;
- }
-
- /**
- * Sets whether the complication, when rendering in ambient mode, should apply a style suitable
- * for display on devices with burn in protection.
- */
- public void setBurnInProtection(boolean burnInProtection) {
- mBurnInProtection = burnInProtection;
- }
-
- /**
- * Whether the complication, when rendering in ambient mode, should apply a style suitable for
- * display on devices with burn in protection.
- */
- public boolean isBurnInProtectionOn() {
- return mBurnInProtection;
- }
-
- /**
- * Sets the current time in mulliseconds since the epoch. This will be used to render
- * {@link ComplicationData} with time dependent text.
- *
- * @param currentTimeMillis time in milliseconds since the epoch
- */
- public void setCurrentTimeMillis(long currentTimeMillis) {
- mCurrentTimeMillis = currentTimeMillis;
- }
-
- /**
- * Returns the time in milliseconds since the epoch used for rendering {@link ComplicationData}
- * with time dependent text.
- */
- public long getCurrentTimeMillis() {
- return mCurrentTimeMillis;
- }
-
- /**
- * Sets whether the complication is currently highlighted. This may be called by a watch face
- * when a complication is tapped.
- *
- * <p>If watch face is in ambient mode, highlight will not be visible even if this is set to
- * {@code true}, because it may cause burn-in or power inefficiency.
- */
- public void setHighlighted(boolean isHighlighted) {
- mHighlighted = isHighlighted;
- }
-
- /**
- * Returns whether the complication is currently highlighted.
- */
- public boolean isHighlighted() {
- return mHighlighted;
- }
-
- /**
- * Sends the tap action for the complication if tap coordinates are inside the complication
- * bounds.
- *
- * <p>This method will also highlight the complication. The highlight duration is 300
- * milliseconds by default but can be modified using the {@link #setHighlightDuration(long)}
- * method.
- *
- * <p>If {@link ComplicationData} has the type {@link ComplicationType#NO_PERMISSION}, this
- * method will launch an intent to request complication permission for the watch face. This will
- * only work if the context set by {@link #getDrawable} or the constructor is an
- * instance of WatchFaceService.
- *
- * @param x X coordinate of the tap relative to screen origin
- * @param y Y coordinate of the tap relative to screen origin
- * @return {@code true} if the action was successful, {@code false} if complication data is not
- * set, the complication has no tap action, the tap action (i.e. {@link
- * android.app.PendingIntent}) is cancelled, or the given x and y are not inside the
- * complication bounds.
- */
- public boolean onTap(@Px int x, @Px int y) {
- if (mComplicationRenderer == null) {
- return false;
- }
- android.support.wearable.complications.ComplicationData data =
- mComplicationRenderer.getComplicationData();
- if (data == null) {
- return false;
- }
- if (!data.hasTapAction() && data.getType()
- != android.support.wearable.complications.ComplicationData.TYPE_NO_PERMISSION) {
- return false;
- }
- if (!getBounds().contains(x, y)) {
- return false;
- }
- if (data.getType()
- == android.support.wearable.complications.ComplicationData.TYPE_NO_PERMISSION) {
- // Check if mContext is an instance of WatchFaceService. We can't use the standard
- // instanceof operator because WatchFaceService is defined in library which depends on
- // this one, hence the reflection hack.
- try {
- if (Class.forName("androidx.wear.watchface.WatchFaceService")
- .isInstance(mContext)) {
- mContext.startActivity(
- ComplicationHelperActivity.createPermissionRequestHelperIntent(
- mContext,
- new ComponentName(mContext, mContext.getClass()))
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
- } else {
- return false;
- }
- } catch (ClassNotFoundException e) {
- // If watchFaceServiceClass class isn't found we know mContext can't be an instance
- // of WatchFaceService.
- return false;
- }
- } else {
- try {
- data.getTapAction().send();
- } catch (CanceledException e) {
- return false;
- }
- }
- if (getHighlightDuration() > 0) {
- setHighlighted(true);
- invalidateSelf();
- mMainThreadHandler.removeCallbacks(mUnhighlightRunnable);
- mMainThreadHandler.postDelayed(mUnhighlightRunnable, getHighlightDuration());
- }
- return true;
- }
-
- /**
- * Sets the duration for the complication to stay highlighted after calling the {@link
- * #onTap(int, int)} method. Default value is 300 milliseconds. Setting highlight duration to 0
- * disables highlighting.
- *
- * @param highlightDurationMillis highlight duration in milliseconds
- */
- public void setHighlightDuration(@IntRange(from = 0) long highlightDurationMillis) {
- if (highlightDurationMillis < 0) {
- throw new IllegalArgumentException("Highlight duration should be non-negative.");
- }
- mHighlightDuration = highlightDurationMillis;
- }
-
- /** Returns the highlight duration. */
- public long getHighlightDuration() {
- return mHighlightDuration;
- }
-
- /** Builds styles and syncs them with the complication renderer. */
- void updateStyleIfRequired() {
- if (mActiveStyle.isDirty() || mAmbientStyle.isDirty()) {
- mComplicationRenderer.updateStyle(mActiveStyle, mAmbientStyle);
- mActiveStyle.clearDirtyFlag();
- mAmbientStyle.clearDirtyFlag();
- }
- }
-
- /**
- * Throws an exception if the context is not set. This method should be called if any of the
- * member methods do a context-dependent job.
- */
- private void assertInitialized() {
- if (mContext == null) {
- throw new IllegalStateException(
- "ComplicationDrawable does not have a context. Use setContext(Context) to set"
- + " it first.");
- }
- }
-
- /** Returns complication style for active mode. */
- @NonNull
- public ComplicationStyle getActiveStyle() {
- return mActiveStyle;
- }
-
- /** Returns complication style for ambient mode. */
- @NonNull
- public ComplicationStyle getAmbientStyle() {
- return mAmbientStyle;
- }
-
- /** Returns complication renderer. */
- @Nullable
- @VisibleForTesting(otherwise = VisibleForTesting.NONE)
- public ComplicationRenderer getComplicationRenderer() {
- return mComplicationRenderer;
- }
-
- /**
- * Returns the text to be rendered when {@link ComplicationData} is of type {@link
- * ComplicationType#NO_DATA}.
- */
- @Nullable
- public CharSequence getNoDataText() {
- return mNoDataText;
- }
-}
diff --git a/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt
new file mode 100644
index 0000000..0639d79
--- /dev/null
+++ b/wear/wear-watchface-complications-rendering/src/main/java/androidx/wear/watchface/complications/rendering/ComplicationDrawable.kt
@@ -0,0 +1,751 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.wear.watchface.complications.rendering
+
+import android.app.PendingIntent
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.res.Resources
+import android.graphics.Canvas
+import android.graphics.ColorFilter
+import android.graphics.Rect
+import android.graphics.Typeface
+import android.graphics.drawable.Drawable
+import android.os.Handler
+import android.os.Looper
+import android.text.TextUtils
+import android.util.AttributeSet
+import android.util.Log
+import android.util.Xml
+import androidx.annotation.IntRange
+import androidx.annotation.Px
+import androidx.annotation.VisibleForTesting
+import androidx.wear.complications.ComplicationHelperActivity
+import androidx.wear.complications.data.ComplicationData
+import androidx.wear.complications.data.ComplicationType.NO_DATA
+import androidx.wear.complications.data.ComplicationType.NO_PERMISSION
+import androidx.wear.complications.data.ComplicationType.RANGED_VALUE
+import androidx.wear.complications.data.toApiComplicationData
+import androidx.wear.watchface.complications.rendering.ComplicationRenderer.OnInvalidateListener
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
+import java.io.IOException
+
+/**
+ * A styleable drawable object that draws complications. You can create a ComplicationDrawable from
+ * XML inflation or by using one of the constructor methods.
+ *
+ * <h3>Constructing a ComplicationDrawable</h3>
+ *
+ * To construct a ComplicationDrawable programmatically, use the [ComplicationDrawable]
+ * constructor. Afterwards, styling attributes you want to modify
+ * can be set via set methods.
+ *
+ * ```
+ * public void onCreate(SurfaceHolder holder) {
+ * ...
+ * ComplicationDrawable complicationDrawable = new ComplicationDrawable(WatchFaceService.this);
+ * complicationDrawable.setBackgroundColorActive(backgroundColor);
+ * complicationDrawable.setTextColorActive(textColor);
+ * ...
+ * }
+ * ```
+ *
+ * <h3>Constructing a ComplicationDrawable from XML</h3>
+ *
+ * Constructing a ComplicationDrawable from an XML file makes it easier to modify multiple
+ * styling attributes at once without calling any set methods. You may also use different XML files
+ * to switch between different styles your watch face supports.
+ *
+ *
+ * To construct a ComplicationDrawable from a drawable XML file, you may create an XML file in
+ * your project's `res/drawable` folder. A ComplicationDrawable with red text and white title
+ * in active mode, and white text and white title in ambient mode would look like this:
+ *
+ * ```
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <android.support.wearable.complications.rendering.ComplicationDrawable
+ * xmlns:app="http://schemas.android.com/apk/res-auto"
+ * app:textColor="#FFFF0000"
+ * app:titleColor="#FFFFFFFF">
+ * <ambient
+ * app:textColor="#FFFFFFFF" />
+ * </android.support.wearable.complications.rendering.ComplicationDrawable>
+ * ```
+ *
+ *
+ * A top-level `drawable` tag with the `class` attribute may also be used to
+ * construct a ComplicationDrawable from an XML file:
+ *
+ * ```
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <drawable
+ * class="android.support.wearable.complications.rendering.ComplicationDrawable"
+ * xmlns:app="http://schemas.android.com/apk/res-auto"
+ * app:textColor="#FFFF0000"
+ * app:titleColor="#FFFFFFFF">
+ * <ambient
+ * app:textColor="#FFFFFFFF" />
+ * </drawable>
+ * ```
+ *
+ * To inflate a ComplicationDrawable from XML file, use the [.getDrawable]
+ * method. ComplicationDrawable needs access to the current context in order to style and draw
+ * the complication.
+ *
+ * ```
+ * public void onCreate(SurfaceHolder holder) {
+ * ...
+ * ComplicationDrawable complicationDrawable = (ComplicationDrawable)
+ * getDrawable(R.drawable.complication);
+ * complicationDrawable.setContext(WatchFaceService.this);
+ * ...
+ * }
+ * ```
+ *
+ * <h4>Syntax:</h4>
+ * ```
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <android.support.wearable.complications.rendering.ComplicationDrawable
+ * xmlns:app="http://schemas.android.com/apk/res-auto"
+ * app:backgroundColor="color"
+ * app:backgroundDrawable="drawable"
+ * app:borderColor="color"
+ * app:borderDashGap="dimension"
+ * app:borderDashWidth="dimension"
+ * app:borderRadius="dimension"
+ * app:borderStyle="none|solid|dashed"
+ * app:borderWidth="dimension"
+ * app:highlightColor="color"
+ * app:iconColor="color"
+ * app:rangedValuePrimaryColor="color"
+ * app:rangedValueProgressHidden="boolean"
+ * app:rangedValueRingWidth="dimension"
+ * app:rangedValueSecondaryColor="color"
+ * app:textColor="color"
+ * app:textSize="dimension"
+ * app:textTypeface="string"
+ * app:titleColor="color"
+ * app:titleSize="dimension"
+ * app:titleTypeface="string">
+ * <ambient
+ * app:backgroundColor="color"
+ * app:backgroundDrawable="drawable"
+ * app:borderColor="color"
+ * app:borderDashGap="dimension"
+ * app:borderDashWidth="dimension"
+ * app:borderRadius="dimension"
+ * app:borderStyle="none|solid|dashed"
+ * app:borderWidth="dimension"
+ * app:highlightColor="color"
+ * app:iconColor="color"
+ * app:rangedValuePrimaryColor="color"
+ * app:rangedValueRingWidth="dimension"
+ * app:rangedValueSecondaryColor="color"
+ * app:textColor="color"
+ * app:textSize="dimension"
+ * app:textTypeface="string"
+ * app:titleColor="color"
+ * app:titleSize="dimension"
+ * app:titleTypeface="string" />
+ * </android.support.wearable.complications.rendering.ComplicationDrawable>
+ * ```
+ *
+ * Attributes of the top-level tag apply to both active and ambient modes while attributes of the
+ * inner `ambient` tag only apply to ambient mode. As an exception, top-level only
+ * `rangedValueProgressHidden` attribute applies to both modes, and cannot be overridden in ambient
+ * mode. To hide ranged value in only one of the active or ambient modes, you may consider setting
+ * `rangedValuePrimaryColor` and `rangedValueSecondaryColor` to [android.graphics.Color.TRANSPARENT]
+ * instead.
+ *
+ * <h3>Drawing a ComplicationDrawable</h3>
+ *
+ * Depending on the size and shape of the bounds, the layout of the complication may change. For
+ * instance, a short text complication with an icon that is drawn on square bounds would draw the
+ * icon above the short text, but a short text complication with an icon that is drawn on wide
+ * rectangular bounds might draw the icon to the left of the short text instead.
+ */
+public class ComplicationDrawable : Drawable {
+ /**
+ * Returns the [Context] used to render the complication.
+ */
+ public var context: Context? = null
+ private set
+
+ /** Returns complication renderer. */
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ @get:JvmName("getComplicationRenderer")
+ internal var complicationRenderer: ComplicationRenderer? = null
+ private set
+
+ /** Returns complication style for active mode. */
+ public val activeStyle: ComplicationStyle
+
+ /** Returns complication style for ambient mode. */
+ public val ambientStyle: ComplicationStyle
+
+ private val mainThreadHandler = Handler(Looper.getMainLooper())
+ private val unhighlightRunnable = Runnable {
+ isHighlighted = false
+ invalidateSelf()
+ }
+ private val rendererInvalidateListener = OnInvalidateListener { invalidateSelf() }
+
+ /**
+ * The time in milliseconds since the epoch used for rendering [ComplicationData]
+ * with time dependent text.
+ */
+ public var currentTimeMillis: Long = 0
+
+ /** Whether the complication is rendered in ambient mode. */
+ public var isInAmbientMode: Boolean = false
+
+ /**
+ * Whether the complication, when rendering in ambient mode, should apply a style
+ * suitable for low bit ambient mode.
+ */
+ public var isLowBitAmbient: Boolean = false
+
+ /**
+ * Whether the complication, when rendering in ambient mode, should apply a style suitable for
+ * display on devices with burn in protection.
+ */
+ public var isBurnInProtectionOn: Boolean = false
+
+ /**
+ * Whether the complication is currently highlighted. This may be called by a watch face
+ * when a complication is tapped.
+ *
+ * If watch face is in ambient mode, highlight will not be visible even if this is set to
+ * `true`, because it may cause burn-in or power inefficiency.
+ */
+ public var isHighlighted: Boolean = false
+
+ private var isInflatedFromXml = false
+ private var alreadyStyled = false
+
+ /** Default constructor. */
+ public constructor() {
+ activeStyle = ComplicationStyle()
+ ambientStyle = ComplicationStyle()
+ }
+
+ /**
+ * Creates a ComplicationDrawable using the given context. If this constructor is used, calling
+ * [.setContext] may not be necessary.
+ */
+ public constructor(context: Context) : this() {
+ setContext(context)
+ }
+
+ public constructor(drawable: ComplicationDrawable) {
+ activeStyle = ComplicationStyle(drawable.activeStyle)
+ ambientStyle = ComplicationStyle(drawable.ambientStyle)
+ noDataText = drawable.noDataText!!.subSequence(0, drawable.noDataText!!.length)
+ highlightDuration = drawable.highlightDuration
+ currentTimeMillis = drawable.currentTimeMillis
+ bounds = drawable.bounds
+ isInAmbientMode = drawable.isInAmbientMode
+ isLowBitAmbient = drawable.isLowBitAmbient
+ isBurnInProtectionOn = drawable.isBurnInProtectionOn
+ isHighlighted = false
+ isRangedValueProgressHidden = drawable.isRangedValueProgressHidden
+ isInflatedFromXml = drawable.isInflatedFromXml
+ alreadyStyled = true
+ }
+
+ /**
+ * Sets the context used to render the complication. If a context is not set,
+ * ComplicationDrawable will throw an [IllegalStateException] if one of [draw], [setBounds],
+ * or [setComplicationData] is called.
+ *
+ * While this can be called from any context, ideally, a
+ * androidx.wear.watchface.WatchFaceService object should be passed here to allow creating
+ * permission dialogs by the [onTap] method, in case current watch face doesn't have the
+ * permission to receive complication data.
+ *
+ * If this ComplicationDrawable is retrieved using [Resources.getDrawable], this method must
+ * be called before calling any of the methods mentioned above.
+ *
+ * If this ComplicationDrawable is not inflated from an XML file, this method will reset the
+ * style to match the default values, so if [ComplicationDrawable()] is used to construct a
+ * ComplicationDrawable, this method should be called right after.
+ */
+ public fun setContext(context: Context) {
+ if (context == this.context) {
+ return
+ }
+ this.context = context
+ if (!isInflatedFromXml && !alreadyStyled) {
+ setStyleToDefaultValues(activeStyle, context.resources)
+ setStyleToDefaultValues(ambientStyle, context.resources)
+ }
+ if (!alreadyStyled) {
+ highlightDuration = context.resources
+ .getInteger(R.integer.complicationDrawable_highlightDurationMs).toLong()
+ }
+ complicationRenderer = ComplicationRenderer(this.context, activeStyle, ambientStyle)
+ val nonNullComplicationRenderer = complicationRenderer!!
+ nonNullComplicationRenderer.setOnInvalidateListener(rendererInvalidateListener)
+ if (noDataText == null) {
+ noDataText = context.getString(R.string.complicationDrawable_noDataText)
+ } else {
+ nonNullComplicationRenderer.setNoDataText(noDataText)
+ }
+ nonNullComplicationRenderer.isRangedValueProgressHidden = isRangedValueProgressHidden
+ nonNullComplicationRenderer.bounds = bounds
+ }
+
+ private fun inflateAttributes(r: Resources, parser: XmlPullParser) {
+ val a = r.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.ComplicationDrawable)
+ isRangedValueProgressHidden =
+ a.getBoolean(R.styleable.ComplicationDrawable_rangedValueProgressHidden, false)
+ a.recycle()
+ }
+
+ private fun inflateStyle(isAmbient: Boolean, r: Resources, parser: XmlPullParser) {
+ val a = r.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.ComplicationDrawable)
+ val complicationStyle = if (isAmbient) ambientStyle else activeStyle
+ if (a.hasValue(R.styleable.ComplicationDrawable_backgroundColor)) {
+ complicationStyle.backgroundColor = a.getColor(
+ R.styleable.ComplicationDrawable_backgroundColor,
+ r.getColor(R.color.complicationDrawable_backgroundColor, null)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_backgroundDrawable)) {
+ complicationStyle.backgroundDrawable =
+ a.getDrawable(R.styleable.ComplicationDrawable_backgroundDrawable)
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_textColor)) {
+ complicationStyle.textColor = a.getColor(
+ R.styleable.ComplicationDrawable_textColor,
+ r.getColor(R.color.complicationDrawable_textColor, null)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_titleColor)) {
+ complicationStyle.titleColor = a.getColor(
+ R.styleable.ComplicationDrawable_titleColor,
+ r.getColor(R.color.complicationDrawable_titleColor, null)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_textTypeface)) {
+ complicationStyle.setTextTypeface(
+ Typeface.create(
+ a.getString(R.styleable.ComplicationDrawable_textTypeface),
+ Typeface.NORMAL
+ )
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_titleTypeface)) {
+ complicationStyle.setTitleTypeface(
+ Typeface.create(
+ a.getString(R.styleable.ComplicationDrawable_titleTypeface),
+ Typeface.NORMAL
+ )
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_textSize)) {
+ complicationStyle.textSize = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_textSize,
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_textSize)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_titleSize)) {
+ complicationStyle.titleSize = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_titleSize,
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_titleSize)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_iconColor)) {
+ complicationStyle.iconColor = a.getColor(
+ R.styleable.ComplicationDrawable_iconColor,
+ r.getColor(R.color.complicationDrawable_iconColor, null)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_borderColor)) {
+ complicationStyle.borderColor = a.getColor(
+ R.styleable.ComplicationDrawable_borderColor,
+ r.getColor(R.color.complicationDrawable_borderColor, null)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_borderRadius)) {
+ complicationStyle.borderRadius = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_borderRadius,
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_borderRadius)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_borderStyle)) {
+ complicationStyle.borderStyle = a.getInt(
+ R.styleable.ComplicationDrawable_borderStyle,
+ r.getInteger(R.integer.complicationDrawable_borderStyle)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_borderDashWidth)) {
+ complicationStyle.borderDashWidth = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_borderDashWidth,
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashWidth)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_borderDashGap)) {
+ complicationStyle.borderDashGap = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_borderDashGap,
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashGap)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_borderWidth)) {
+ complicationStyle.borderWidth = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_borderWidth,
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_borderWidth)
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_rangedValueRingWidth)) {
+ complicationStyle.rangedValueRingWidth = a.getDimensionPixelSize(
+ R.styleable.ComplicationDrawable_rangedValueRingWidth,
+ r.getDimensionPixelSize(
+ R.dimen.complicationDrawable_rangedValueRingWidth
+ )
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_rangedValuePrimaryColor)) {
+ complicationStyle.rangedValuePrimaryColor = a.getColor(
+ R.styleable.ComplicationDrawable_rangedValuePrimaryColor,
+ r.getColor(
+ R.color.complicationDrawable_rangedValuePrimaryColor, null
+ )
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_rangedValueSecondaryColor)) {
+ complicationStyle.rangedValueSecondaryColor = a.getColor(
+ R.styleable.ComplicationDrawable_rangedValueSecondaryColor,
+ r.getColor(
+ R.color.complicationDrawable_rangedValueSecondaryColor, null
+ )
+ )
+ }
+ if (a.hasValue(R.styleable.ComplicationDrawable_highlightColor)) {
+ complicationStyle.highlightColor = a.getColor(
+ R.styleable.ComplicationDrawable_highlightColor,
+ r.getColor(R.color.complicationDrawable_highlightColor, null)
+ )
+ }
+ a.recycle()
+ }
+
+ /**
+ * Inflates this ComplicationDrawable from an XML resource. This can't be called more than once
+ * for each ComplicationDrawable. Note that framework may have called this once to create the
+ * ComplicationDrawable instance from an XML resource.
+ *
+ * @param r Resources used to resolve attribute values
+ * @param parser XML parser from which to inflate this ComplicationDrawable
+ * @param attrs Base set of attribute values
+ * @param theme Ignored by ComplicationDrawable
+ */
+ @Throws(XmlPullParserException::class, IOException::class)
+ public override fun inflate(
+ r: Resources,
+ parser: XmlPullParser,
+ attrs: AttributeSet,
+ theme: Resources.Theme?
+ ) {
+ check(!isInflatedFromXml) { "inflate may be called once only." }
+ isInflatedFromXml = true
+ var type: Int
+ val outerDepth = parser.depth
+ // Inflate attributes always shared between active and ambient mode
+ inflateAttributes(r, parser)
+ // Reset both style builders to default values
+ setStyleToDefaultValues(activeStyle, r)
+ setStyleToDefaultValues(ambientStyle, r)
+ // Attributes of the outer tag applies to both active and ambient styles
+ inflateStyle(false, r, parser)
+ inflateStyle(true, r, parser)
+ while (
+ parser.next().also { type = it } != XmlPullParser.END_DOCUMENT &&
+ (type != XmlPullParser.END_TAG || parser.depth > outerDepth)
+ ) {
+ if (type != XmlPullParser.START_TAG) {
+ continue
+ }
+
+ // Attributes of inner <ambient> tag applies to ambient style only
+ val name = parser.name
+ if (TextUtils.equals(name, "ambient")) {
+ inflateStyle(true, r, parser)
+ } else {
+ Log.w(
+ "ComplicationDrawable",
+ "Unknown element: $name for ComplicationDrawable $this"
+ )
+ }
+ }
+ }
+
+ /**
+ * Draws the complication for the last known time. Last known time is derived from
+ * ComplicationDrawable#setCurrentTimeMillis(long)}.
+ *
+ * @param canvas Canvas for the complication to be drawn onto
+ */
+ public override fun draw(canvas: Canvas) {
+ assertInitialized()
+ updateStyleIfRequired()
+ complicationRenderer?.draw(
+ canvas,
+ currentTimeMillis,
+ isInAmbientMode,
+ isLowBitAmbient,
+ isBurnInProtectionOn,
+ isHighlighted
+ )
+ }
+
+ /**
+ * This function is not supported in [ComplicationDrawable].
+ *
+ * @throws [UnsupportedOperationException] when called.
+ */
+ public override fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) {
+ throw UnsupportedOperationException("setAlpha is not supported in ComplicationDrawable.")
+ }
+
+ /**
+ * This function is not supported in [ComplicationDrawable]. Use
+ * [ComplicationStyle.imageColorFilter] instead to apply color filter to small and large images.
+ *
+ * @throws [UnsupportedOperationException] when called.
+ */
+ public override fun setColorFilter(colorFilter: ColorFilter?) {
+ throw UnsupportedOperationException(
+ "setColorFilter is not supported in ComplicationDrawable."
+ )
+ }
+
+ /** @throws [UnsupportedOperationException] when called. */
+ @Deprecated("This method is no longer used in graphics optimizations")
+ override fun getOpacity(): Int =
+ throw UnsupportedOperationException("getOpacity is not supported in ComplicationDrawable.")
+
+ protected override fun onBoundsChange(bounds: Rect) {
+ if (complicationRenderer != null) {
+ complicationRenderer!!.bounds = bounds
+ }
+ }
+
+ /** If the ranged value progress should be hidden when [ComplicationData] is of type
+ * [RANGED_VALUE].
+ *
+ * @attr ref androidx.wear.watchface.complications.rendering.R
+ * .styleable#ComplicationDrawable_rangedValueProgressHidden
+ */
+ public var isRangedValueProgressHidden: Boolean = false
+ set(rangedValueProgressHidden) {
+ field = rangedValueProgressHidden
+ complicationRenderer?.isRangedValueProgressHidden = rangedValueProgressHidden
+ }
+
+ /**
+ * Sets the complication data to be drawn. If `complicationData` is `null`, nothing
+ * will be drawn when [draw] is called.
+ *
+ * @param complicationData The [ComplicationData] to set
+ * @param loadDrawablesAsync If true any drawables should be loaded asynchronously,
+ * otherwise they will be loaded synchronously.
+ */
+ public fun setComplicationData(
+ complicationData: ComplicationData?,
+ loadDrawablesAsync: Boolean
+ ) {
+ assertInitialized()
+ complicationRenderer?.setComplicationData(
+ complicationData?.asWireComplicationData(),
+ loadDrawablesAsync
+ )
+ }
+
+ /**
+ * Returns the [ComplicationData] to be drawn by this ComplicationDrawable.
+ */
+ public val complicationData: ComplicationData?
+ get() = if (complicationRenderer?.complicationData != null)
+ complicationRenderer!!.complicationData.toApiComplicationData()
+ else null
+
+ /**
+ * Sends the tap action for the complication if tap coordinates are inside the complication
+ * bounds.
+ *
+ * This method will also highlight the complication. The highlight duration is 300
+ * milliseconds by default but can be modified using the [.setHighlightDuration]
+ * method.
+ *
+ * If [ComplicationData] has the type [NO_PERMISSION], this method will launch an intent to
+ * request complication permission for the watch face. This will only work if the context set
+ * by [getDrawable] or the constructor is an instance of WatchFaceService.
+ *
+ * @param x X coordinate of the tap relative to screen origin
+ * @param y Y coordinate of the tap relative to screen origin
+ * @return `true` if the action was successful, `false` if complication data is not set, the
+ * complication has no tap action, the tap action (i.e. [android.app.PendingIntent]) is
+ * cancelled, or the given x and y are not inside the complication bounds.
+ */
+ public fun onTap(@Px x: Int, @Px y: Int): Boolean {
+ if (complicationRenderer == null) {
+ return false
+ }
+ val data = complicationRenderer!!.complicationData ?: return false
+ if (!data.hasTapAction() && data.type
+ != android.support.wearable.complications.ComplicationData.TYPE_NO_PERMISSION
+ ) {
+ return false
+ }
+ if (!bounds.contains(x, y)) {
+ return false
+ }
+ if (data.type
+ == android.support.wearable.complications.ComplicationData.TYPE_NO_PERMISSION
+ ) {
+ // Check if context is an instance of WatchFaceService. We can't use the standard
+ // instanceof operator because WatchFaceService is defined in library which depends on
+ // this one, hence the reflection hack.
+ try {
+ if (context!!::class.java.name == "androidx.wear.watchface.WatchFaceService") {
+ context!!.startActivity(
+ ComplicationHelperActivity.createPermissionRequestHelperIntent(
+ context!!,
+ ComponentName(context!!, context!!.javaClass)
+ )
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ )
+ } else {
+ return false
+ }
+ } catch (e: ClassNotFoundException) {
+ // If watchFaceServiceClass class isn't found we know context can't be an instance
+ // of WatchFaceService.
+ return false
+ }
+ } else {
+ try {
+ data.tapAction!!.send()
+ } catch (e: PendingIntent.CanceledException) {
+ return false
+ }
+ }
+ if (highlightDuration > 0) {
+ isHighlighted = true
+ invalidateSelf()
+ mainThreadHandler.removeCallbacks(unhighlightRunnable)
+ mainThreadHandler.postDelayed(unhighlightRunnable, highlightDuration)
+ }
+ return true
+ }
+
+ /** The duration for the complication to stay highlighted after calling the [onTap] method.
+ * Default value is 300 milliseconds. Setting highlight duration to 0 disables highlighting.
+ */
+ public var highlightDuration: Long = 0
+ set(@IntRange(from = 0) highlightDurationMillis: Long) {
+ require(highlightDurationMillis >= 0) { "Highlight duration should be non-negative." }
+ field = highlightDurationMillis
+ }
+
+ /** Builds styles and syncs them with the complication renderer. */
+ @JvmName(name = "updateStyleIfRequired")
+ internal fun updateStyleIfRequired() {
+ if (activeStyle.isDirty || ambientStyle.isDirty) {
+ complicationRenderer!!.updateStyle(activeStyle, ambientStyle)
+ activeStyle.clearDirtyFlag()
+ ambientStyle.clearDirtyFlag()
+ }
+ }
+
+ /**
+ * Throws an exception if the context is not set. This method should be called if any of the
+ * member methods do a context-dependent job.
+ */
+ private fun assertInitialized() {
+ checkNotNull(context) {
+ "ComplicationDrawable does not have a context. Use setContext(Context) to set it first."
+ }
+ }
+ /**
+ * The text to be rendered when [ComplicationData] is of type [NO_DATA]. If `noDataText` is
+ * null, an empty text will be
+ * rendered.
+ */
+ public var noDataText: CharSequence? = null
+ set(noDataText) {
+ field = noDataText?.subSequence(0, noDataText.length) ?: ""
+ if (complicationRenderer != null) {
+ complicationRenderer!!.setNoDataText(field)
+ }
+ }
+
+ public companion object {
+ /**
+ * Creates a ComplicationDrawable from a resource.
+ *
+ * @param context The [Context] to load the resource from
+ * @param id The id of the resource to load
+ * @return The [ComplicationDrawable] loaded from the specified resource id or null if it
+ * doesn't exist.
+ */
+ @JvmStatic
+ public fun getDrawable(context: Context, id: Int): ComplicationDrawable? {
+ val drawable = context.getDrawable(id) as ComplicationDrawable? ?: return null
+ drawable.setContext(context)
+ return drawable
+ }
+
+ /** Sets the style to default values using resources. */
+ @JvmStatic
+ internal fun setStyleToDefaultValues(style: ComplicationStyle, r: Resources) {
+ style.backgroundColor = r.getColor(R.color.complicationDrawable_backgroundColor, null)
+ style.textColor = r.getColor(R.color.complicationDrawable_textColor, null)
+ style.titleColor = r.getColor(R.color.complicationDrawable_titleColor, null)
+ style.setTextTypeface(
+ Typeface.create(
+ r.getString(R.string.complicationDrawable_textTypeface), Typeface.NORMAL
+ )
+ )
+ style.setTitleTypeface(
+ Typeface.create(
+ r.getString(R.string.complicationDrawable_titleTypeface), Typeface.NORMAL
+ )
+ )
+ style.textSize = r.getDimensionPixelSize(R.dimen.complicationDrawable_textSize)
+ style.titleSize = r.getDimensionPixelSize(R.dimen.complicationDrawable_titleSize)
+ style.iconColor = r.getColor(R.color.complicationDrawable_iconColor, null)
+ style.borderColor = r.getColor(R.color.complicationDrawable_borderColor, null)
+ style.borderWidth = r.getDimensionPixelSize(R.dimen.complicationDrawable_borderWidth)
+ style.borderRadius = r.getDimensionPixelSize(R.dimen.complicationDrawable_borderRadius)
+ style.borderStyle = r.getInteger(R.integer.complicationDrawable_borderStyle)
+ style.borderDashWidth =
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashWidth)
+ style.borderDashGap =
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_borderDashGap)
+ style.rangedValueRingWidth =
+ r.getDimensionPixelSize(R.dimen.complicationDrawable_rangedValueRingWidth)
+ style.rangedValuePrimaryColor =
+ r.getColor(R.color.complicationDrawable_rangedValuePrimaryColor, null)
+ style.rangedValueSecondaryColor =
+ r.getColor(R.color.complicationDrawable_rangedValueSecondaryColor, null)
+ style.highlightColor = r.getColor(R.color.complicationDrawable_highlightColor, null)
+ }
+ }
+}
\ No newline at end of file
diff --git a/wear/wear-watchface-complications-rendering/src/test/java/androidx/wear/watchface/complications/rendering/ComplicationDrawableTest.java b/wear/wear-watchface-complications-rendering/src/test/java/androidx/wear/watchface/complications/rendering/ComplicationDrawableTest.java
index 223c731..ed6f874c 100644
--- a/wear/wear-watchface-complications-rendering/src/test/java/androidx/wear/watchface/complications/rendering/ComplicationDrawableTest.java
+++ b/wear/wear-watchface-complications-rendering/src/test/java/androidx/wear/watchface/complications/rendering/ComplicationDrawableTest.java
@@ -120,11 +120,6 @@
}
@Test
- public void callingSetContextWithNullThrowsIllegalArgumentException() {
- assertThrows(IllegalArgumentException.class, () -> mComplicationDrawable.setContext(null));
- }
-
- @Test
public void callingDrawOnCanvasBeforeSetContextThrowsAnException() {
assertThrows(IllegalStateException.class, () -> mComplicationDrawable.draw(mMockCanvas));
}
diff --git a/wear/wear-watchface-data/api/restricted_current.txt b/wear/wear-watchface-data/api/restricted_current.txt
index 98430d9..16f5ad0 100644
--- a/wear/wear-watchface-data/api/restricted_current.txt
+++ b/wear/wear-watchface-data/api/restricted_current.txt
@@ -308,7 +308,7 @@
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @androidx.versionedparcelable.VersionedParcelize public class ComplicationOverlayWireFormat implements android.os.Parcelable androidx.versionedparcelable.VersionedParcelable {
- ctor public ComplicationOverlayWireFormat(int, Boolean?, java.util.Map<androidx.wear.complications.data.ComplicationType!,android.graphics.RectF!>?, Integer?);
+ ctor public ComplicationOverlayWireFormat(int, Boolean?, java.util.Map<java.lang.Integer!,android.graphics.RectF!>?, Integer?);
method public int describeContents();
method public Integer? getAccessibilityTraversalIndex();
method public void writeToParcel(android.os.Parcel, int);
@@ -319,7 +319,7 @@
field public static final long NULL_ACCESSIBILITY_TRAVERSAL_INDEX = 4294967296L; // 0x100000000L
field @androidx.versionedparcelable.ParcelField(1) public int mComplicationId;
field @androidx.versionedparcelable.ParcelField(2) public int mEnabled;
- field @androidx.versionedparcelable.ParcelField(3) public java.util.Map<androidx.wear.complications.data.ComplicationType!,android.graphics.RectF!>? mPerComplicationTypeBounds;
+ field @androidx.versionedparcelable.ParcelField(3) public java.util.Map<java.lang.Integer!,android.graphics.RectF!>? mPerComplicationTypeBounds;
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @androidx.versionedparcelable.VersionedParcelize public class ComplicationsOptionWireFormat extends androidx.wear.watchface.style.data.OptionWireFormat {
diff --git a/wear/wear-watchface-data/src/main/java/androidx/wear/watchface/style/data/ComplicationOverlayWireFormat.java b/wear/wear-watchface-data/src/main/java/androidx/wear/watchface/style/data/ComplicationOverlayWireFormat.java
index 71ebc33..e63e83b 100644
--- a/wear/wear-watchface-data/src/main/java/androidx/wear/watchface/style/data/ComplicationOverlayWireFormat.java
+++ b/wear/wear-watchface-data/src/main/java/androidx/wear/watchface/style/data/ComplicationOverlayWireFormat.java
@@ -28,7 +28,6 @@
import androidx.versionedparcelable.ParcelUtils;
import androidx.versionedparcelable.VersionedParcelable;
import androidx.versionedparcelable.VersionedParcelize;
-import androidx.wear.complications.data.ComplicationType;
import java.util.Map;
@@ -54,7 +53,7 @@
@ParcelField(3)
@Nullable
- public Map<ComplicationType, RectF> mPerComplicationTypeBounds;
+ public Map<Integer, RectF> mPerComplicationTypeBounds;
/** Ideally this would be Integer but VersionedParcelable doesn't support that. */
@ParcelField(4)
@@ -66,7 +65,7 @@
public ComplicationOverlayWireFormat(
int complicationId,
@Nullable Boolean enabled,
- @Nullable Map<ComplicationType, RectF> perComplicationTypeBounds,
+ @Nullable Map<Integer, RectF> perComplicationTypeBounds,
@Nullable Integer accessibilityTraversalIndex
) {
mComplicationId = complicationId;
diff --git a/wear/wear-watchface-editor/lint-baseline.xml b/wear/wear-watchface-editor/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-watchface-editor/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface-editor/samples/lint-baseline.xml b/wear/wear-watchface-editor/samples/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-watchface-editor/samples/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface-style/lint-baseline.xml b/wear/wear-watchface-style/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-watchface-style/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
index 55a881d..d3169ac 100644
--- a/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
+++ b/wear/wear-watchface-style/src/main/java/androidx/wear/watchface/style/UserStyleSetting.kt
@@ -19,6 +19,7 @@
import android.graphics.drawable.Icon
import androidx.annotation.RestrictTo
import androidx.wear.complications.ComplicationBounds
+import androidx.wear.complications.data.ComplicationType
import androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationOverlay
import androidx.wear.watchface.style.UserStyleSetting.ComplicationsUserStyleSetting.ComplicationsOption
import androidx.wear.watchface.style.UserStyleSetting.Id.Companion.MAX_LENGTH
@@ -438,7 +439,11 @@
"Unrecognised wireFormat.mEnabled " + wireFormat.mEnabled
)
},
- wireFormat.mPerComplicationTypeBounds?.let { ComplicationBounds(it) },
+ wireFormat.mPerComplicationTypeBounds?.let {
+ ComplicationBounds(
+ it.mapKeys { ComplicationType.fromWireType(it.key) }
+ )
+ },
wireFormat.accessibilityTraversalIndex
)
@@ -446,7 +451,9 @@
ComplicationOverlayWireFormat(
complicationId,
enabled,
- complicationBounds?.perComplicationTypeBounds,
+ complicationBounds?.perComplicationTypeBounds?.mapKeys {
+ it.key.toWireComplicationType()
+ },
accessibilityTraversalIndex
)
}
diff --git a/wear/wear-watchface/samples/lint-baseline.xml b/wear/wear-watchface/samples/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/wear/wear-watchface/samples/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/BroadcastReceivers.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/BroadcastReceivers.kt
deleted file mode 100644
index 322a004..0000000
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/BroadcastReceivers.kt
+++ /dev/null
@@ -1,215 +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.wear.watchface
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import androidx.annotation.UiThread
-import androidx.annotation.VisibleForTesting
-
-/**
- * All watchface instances share the same [Context] which is a problem for broadcast receivers
- * because the OS will mistakenly believe we're leaking them if there's more than one instance. So
- * we need to use this class to share them.
- */
-internal class BroadcastReceivers private constructor(private val context: Context) {
-
- interface BroadcastEventObserver {
- /** Called when we receive [Intent.ACTION_TIME_TICK]. */
- @UiThread
- fun onActionTimeTick()
-
- /** Called when we receive [Intent.ACTION_TIMEZONE_CHANGED]. */
- @UiThread
- fun onActionTimeZoneChanged()
-
- /** Called when we receive [Intent.ACTION_TIME_CHANGED]. */
- @UiThread
- fun onActionTimeChanged()
-
- /** Called when we receive [Intent.ACTION_BATTERY_LOW]. */
- @UiThread
- fun onActionBatteryLow()
-
- /** Called when we receive [Intent.ACTION_BATTERY_OKAY]. */
- @UiThread
- fun onActionBatteryOkay()
-
- /** Called when we receive [Intent.ACTION_POWER_CONNECTED]. */
- @UiThread
- fun onActionPowerConnected()
-
- /** Called when we receive [WatchFaceImpl.MOCK_TIME_INTENT]. */
- @UiThread
- fun onMockTime(intent: Intent)
- }
-
- companion object {
- val broadcastEventObservers = HashSet<BroadcastEventObserver>()
-
- /**
- * We don't leak due to balanced calls to [addBroadcastEventObserver] and
- * [removeBroadcastEventObserver] which sets this back to null.
- */
- @SuppressWarnings("StaticFieldLeak")
- var broadcastReceivers: BroadcastReceivers? = null
-
- @UiThread
- fun addBroadcastEventObserver(context: Context, observer: BroadcastEventObserver) {
- broadcastEventObservers.add(observer)
- if (broadcastReceivers == null) {
- broadcastReceivers = BroadcastReceivers(context)
- }
- }
-
- @UiThread
- fun removeBroadcastEventObserver(observer: BroadcastEventObserver) {
- if (broadcastEventObservers.remove(observer) && broadcastEventObservers.isEmpty()) {
- broadcastReceivers!!.onDestroy()
- broadcastReceivers = null
- }
- }
-
- @VisibleForTesting
- fun sendOnActionBatteryLowForTesting(intent: Intent) {
- require(intent.action == Intent.ACTION_BATTERY_LOW)
- require(broadcastEventObservers.isNotEmpty())
- for (observer in broadcastEventObservers) {
- observer.onActionBatteryLow()
- }
- }
-
- @VisibleForTesting
- fun sendOnActionBatteryOkayForTesting(intent: Intent) {
- require(intent.action == Intent.ACTION_BATTERY_OKAY)
- require(broadcastEventObservers.isNotEmpty())
- for (observer in broadcastEventObservers) {
- observer.onActionBatteryOkay()
- }
- }
-
- @VisibleForTesting
- fun sendOnActionPowerConnectedForTesting(intent: Intent) {
- require(intent.action == Intent.ACTION_POWER_CONNECTED)
- require(broadcastEventObservers.isNotEmpty())
- for (observer in broadcastEventObservers) {
- observer.onActionPowerConnected()
- }
- }
-
- @VisibleForTesting
- fun sendOnMockTimeForTesting(intent: Intent) {
- require(intent.action == WatchFaceImpl.MOCK_TIME_INTENT)
- require(broadcastEventObservers.isNotEmpty())
- for (observer in broadcastEventObservers) {
- observer.onMockTime(intent)
- }
- }
- }
-
- private val actionTimeTickReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- @SuppressWarnings("SyntheticAccessor")
- override fun onReceive(context: Context, intent: Intent) {
- for (observer in broadcastEventObservers) {
- observer.onActionTimeTick()
- }
- }
- }
-
- private val actionTimeZoneReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- for (observer in broadcastEventObservers) {
- observer.onActionTimeZoneChanged()
- }
- }
- }
-
- private val actionTimeReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
- for (observer in broadcastEventObservers) {
- observer.onActionTimeChanged()
- }
- }
- }
-
- private val actionBatteryLowReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- @SuppressWarnings("SyntheticAccessor")
- override fun onReceive(context: Context, intent: Intent) {
- for (observer in broadcastEventObservers) {
- observer.onActionBatteryLow()
- }
- }
- }
-
- private val actionBatteryOkayReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- @SuppressWarnings("SyntheticAccessor")
- override fun onReceive(context: Context, intent: Intent) {
- for (observer in broadcastEventObservers) {
- observer.onActionBatteryOkay()
- }
- }
- }
-
- private val actionPowerConnectedReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- @SuppressWarnings("SyntheticAccessor")
- override fun onReceive(context: Context, intent: Intent) {
- for (observer in broadcastEventObservers) {
- observer.onActionPowerConnected()
- }
- }
- }
-
- private val mockTimeReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- @SuppressWarnings("SyntheticAccessor")
- override fun onReceive(context: Context, intent: Intent) {
- for (observer in broadcastEventObservers) {
- observer.onMockTime(intent)
- }
- }
- }
-
- init {
- context.registerReceiver(actionTimeTickReceiver, IntentFilter(Intent.ACTION_TIME_TICK))
- context.registerReceiver(
- actionTimeZoneReceiver,
- IntentFilter(Intent.ACTION_TIMEZONE_CHANGED)
- )
- context.registerReceiver(actionTimeReceiver, IntentFilter(Intent.ACTION_TIME_CHANGED))
- context.registerReceiver(actionBatteryLowReceiver, IntentFilter(Intent.ACTION_BATTERY_LOW))
- context.registerReceiver(
- actionBatteryOkayReceiver,
- IntentFilter(Intent.ACTION_BATTERY_OKAY)
- )
- context.registerReceiver(
- actionPowerConnectedReceiver,
- IntentFilter(Intent.ACTION_POWER_CONNECTED)
- )
- context.registerReceiver(mockTimeReceiver, IntentFilter(WatchFaceImpl.MOCK_TIME_INTENT))
- }
-
- fun onDestroy() {
- context.unregisterReceiver(actionTimeTickReceiver)
- context.unregisterReceiver(actionTimeZoneReceiver)
- context.unregisterReceiver(actionTimeReceiver)
- context.unregisterReceiver(actionBatteryLowReceiver)
- context.unregisterReceiver(actionBatteryOkayReceiver)
- context.unregisterReceiver(actionPowerConnectedReceiver)
- context.unregisterReceiver(mockTimeReceiver)
- }
-}
\ No newline at end of file
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/BroadcastsReceiver.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/BroadcastsReceiver.kt
new file mode 100644
index 0000000..cc6675a
--- /dev/null
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/BroadcastsReceiver.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.watchface
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import androidx.annotation.UiThread
+
+/**
+ * This class decouples [BroadcastEventObserver]s from the actual broadcast event receivers to make
+ * testing easier.
+ */
+internal class BroadcastsReceiver constructor(
+ private val context: Context,
+ private val observer: BroadcastEventObserver
+) {
+
+ interface BroadcastEventObserver {
+ /** Called when we receive [Intent.ACTION_TIME_TICK]. */
+ @UiThread
+ fun onActionTimeTick()
+
+ /** Called when we receive [Intent.ACTION_TIMEZONE_CHANGED]. */
+ @UiThread
+ fun onActionTimeZoneChanged()
+
+ /** Called when we receive [Intent.ACTION_TIME_CHANGED]. */
+ @UiThread
+ fun onActionTimeChanged()
+
+ /** Called when we receive [Intent.ACTION_BATTERY_LOW]. */
+ @UiThread
+ fun onActionBatteryLow()
+
+ /** Called when we receive [Intent.ACTION_BATTERY_OKAY]. */
+ @UiThread
+ fun onActionBatteryOkay()
+
+ /** Called when we receive [Intent.ACTION_POWER_CONNECTED]. */
+ @UiThread
+ fun onActionPowerConnected()
+
+ /** Called when we receive [WatchFaceImpl.MOCK_TIME_INTENT]. */
+ @UiThread
+ fun onMockTime(intent: Intent)
+ }
+
+ internal val actionTimeTickReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ @SuppressWarnings("SyntheticAccessor")
+ override fun onReceive(context: Context, intent: Intent) {
+ observer.onActionTimeTick()
+ }
+ }
+
+ internal val actionTimeZoneReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ observer.onActionTimeZoneChanged()
+ }
+ }
+
+ internal val actionTimeReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ observer.onActionTimeChanged()
+ }
+ }
+
+ internal val actionBatteryLowReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ @SuppressWarnings("SyntheticAccessor")
+ override fun onReceive(context: Context, intent: Intent) {
+ observer.onActionBatteryLow()
+ }
+ }
+
+ internal val actionBatteryOkayReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ @SuppressWarnings("SyntheticAccessor")
+ override fun onReceive(context: Context, intent: Intent) {
+ observer.onActionBatteryOkay()
+ }
+ }
+
+ internal val actionPowerConnectedReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ @SuppressWarnings("SyntheticAccessor")
+ override fun onReceive(context: Context, intent: Intent) {
+ observer.onActionPowerConnected()
+ }
+ }
+
+ internal val mockTimeReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ @SuppressWarnings("SyntheticAccessor")
+ override fun onReceive(context: Context, intent: Intent) {
+ observer.onMockTime(intent)
+ }
+ }
+
+ init {
+ context.registerReceiver(actionTimeTickReceiver, IntentFilter(Intent.ACTION_TIME_TICK))
+ context.registerReceiver(
+ actionTimeZoneReceiver,
+ IntentFilter(Intent.ACTION_TIMEZONE_CHANGED)
+ )
+ context.registerReceiver(actionTimeReceiver, IntentFilter(Intent.ACTION_TIME_CHANGED))
+ context.registerReceiver(actionBatteryLowReceiver, IntentFilter(Intent.ACTION_BATTERY_LOW))
+ context.registerReceiver(
+ actionBatteryOkayReceiver,
+ IntentFilter(Intent.ACTION_BATTERY_OKAY)
+ )
+ context.registerReceiver(
+ actionPowerConnectedReceiver,
+ IntentFilter(Intent.ACTION_POWER_CONNECTED)
+ )
+ context.registerReceiver(mockTimeReceiver, IntentFilter(WatchFaceImpl.MOCK_TIME_INTENT))
+ }
+
+ fun onDestroy() {
+ context.unregisterReceiver(actionTimeTickReceiver)
+ context.unregisterReceiver(actionTimeZoneReceiver)
+ context.unregisterReceiver(actionTimeReceiver)
+ context.unregisterReceiver(actionBatteryLowReceiver)
+ context.unregisterReceiver(actionBatteryOkayReceiver)
+ context.unregisterReceiver(actionPowerConnectedReceiver)
+ context.unregisterReceiver(mockTimeReceiver)
+ }
+}
\ No newline at end of file
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
index 27a58d2..09eca33 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/Complication.kt
@@ -445,7 +445,9 @@
// The caller might modify a number of complications. For efficiency we need to coalesce
// these into one update task.
- complicationsManager.scheduleUpdate()
+ if (this::complicationsManager.isInitialized) {
+ complicationsManager.scheduleUpdate()
+ }
}
internal var enabledDirty = true
diff --git a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
index 2153570..8dbc10c 100644
--- a/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
+++ b/wear/wear-watchface/src/main/java/androidx/wear/watchface/WatchFace.kt
@@ -435,7 +435,7 @@
private var mockTime = MockTime(1.0, 0, Long.MAX_VALUE)
private var lastTappedComplicationId: Int? = null
- private var registeredReceivers = false
+ internal var broadcastsReceiver: BroadcastsReceiver? = null
// True if 'Do Not Disturb' mode is on.
private var muteMode = false
@@ -465,7 +465,7 @@
legacyWatchFaceStyle.tapEventsAccepted
)
- private val broadcastEventObserver = object : BroadcastReceivers.BroadcastEventObserver {
+ private val broadcastEventObserver = object : BroadcastsReceiver.BroadcastEventObserver {
override fun onActionTimeTick() {
if (!watchState.isAmbient.value) {
renderer.invalidate()
@@ -759,14 +759,12 @@
require(watchFaceHostApi.getHandler().looper.isCurrentThread) {
"registerReceivers must be called the UiThread"
}
- if (registeredReceivers) {
- return
+
+ // There's no point registering BroadcastsReceiver for headless instances.
+ if (broadcastsReceiver == null && !watchState.isHeadless) {
+ broadcastsReceiver =
+ BroadcastsReceiver(watchFaceHostApi.getContext(), broadcastEventObserver)
}
- registeredReceivers = true
- BroadcastReceivers.addBroadcastEventObserver(
- watchFaceHostApi.getContext(),
- broadcastEventObserver
- )
}
@UiThread
@@ -774,11 +772,8 @@
require(watchFaceHostApi.getHandler().looper.isCurrentThread) {
"unregisterReceivers must be called the UiThread"
}
- if (!registeredReceivers) {
- return
- }
- registeredReceivers = false
- BroadcastReceivers.removeBroadcastEventObserver(broadcastEventObserver)
+ broadcastsReceiver?.onDestroy()
+ broadcastsReceiver = null
}
private fun scheduleDraw() {
diff --git a/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt b/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt
index fd55a85..118cb31 100644
--- a/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt
+++ b/wear/wear-watchface/src/test/java/androidx/wear/watchface/WatchFaceServiceTest.kt
@@ -624,7 +624,8 @@
watchState.isAmbient.value = false
testWatchFaceService.mockSystemTimeMillis = 1000L
- BroadcastReceivers.sendOnMockTimeForTesting(
+ watchFaceImpl.broadcastsReceiver!!.mockTimeReceiver.onReceive(
+ context,
Intent(WatchFaceImpl.MOCK_TIME_INTENT).apply {
putExtra(WatchFaceImpl.EXTRA_MOCK_TIME_SPEED_MULTIPLIER, 2.0f)
putExtra(WatchFaceImpl.EXTRA_MOCK_TIME_WRAPPING_MIN_TIME, -1L)
@@ -651,7 +652,8 @@
watchState.isAmbient.value = false
testWatchFaceService.mockSystemTimeMillis = 1000L
- BroadcastReceivers.sendOnMockTimeForTesting(
+ watchFaceImpl.broadcastsReceiver!!.mockTimeReceiver.onReceive(
+ context,
Intent(WatchFaceImpl.MOCK_TIME_INTENT).apply {
putExtra(WatchFaceImpl.EXTRA_MOCK_TIME_SPEED_MULTIPLIER, 2.0f)
putExtra(WatchFaceImpl.EXTRA_MOCK_TIME_WRAPPING_MIN_TIME, 1000L)
@@ -857,13 +859,19 @@
)
// The delay should change when battery is low.
- BroadcastReceivers.sendOnActionBatteryLowForTesting(Intent(Intent.ACTION_BATTERY_LOW))
+ watchFaceImpl.broadcastsReceiver!!.actionBatteryLowReceiver.onReceive(
+ context,
+ Intent(Intent.ACTION_BATTERY_LOW)
+ )
assertThat(watchFaceImpl.computeDelayTillNextFrame(0, 0)).isEqualTo(
WatchFaceImpl.MAX_LOW_POWER_INTERACTIVE_UPDATE_RATE_MS
)
// And go back to normal when battery is OK.
- BroadcastReceivers.sendOnActionBatteryOkayForTesting(Intent(Intent.ACTION_BATTERY_OKAY))
+ watchFaceImpl.broadcastsReceiver!!.actionBatteryOkayReceiver.onReceive(
+ context,
+ Intent(Intent.ACTION_BATTERY_OKAY)
+ )
assertThat(watchFaceImpl.computeDelayTillNextFrame(0, 0)).isEqualTo(
INTERACTIVE_UPDATE_RATE_MS
)
@@ -882,13 +890,17 @@
)
// The delay should change when battery is low.
- BroadcastReceivers.sendOnActionBatteryLowForTesting(Intent(Intent.ACTION_BATTERY_LOW))
+ watchFaceImpl.broadcastsReceiver!!.actionBatteryLowReceiver.onReceive(
+ context,
+ Intent(Intent.ACTION_BATTERY_LOW)
+ )
assertThat(watchFaceImpl.computeDelayTillNextFrame(0, 0)).isEqualTo(
WatchFaceImpl.MAX_LOW_POWER_INTERACTIVE_UPDATE_RATE_MS
)
// And go back to normal when power is connected.
- BroadcastReceivers.sendOnActionPowerConnectedForTesting(
+ watchFaceImpl.broadcastsReceiver!!.actionPowerConnectedReceiver.onReceive(
+ context,
Intent(Intent.ACTION_POWER_CONNECTED)
)
assertThat(watchFaceImpl.computeDelayTillNextFrame(0, 0)).isEqualTo(
@@ -2536,13 +2548,35 @@
}
@Test
- public fun double_BroadcastReceivers_removeBroadcastEventObserver() {
- val observer = mock<BroadcastReceivers.BroadcastEventObserver>()
- BroadcastReceivers.addBroadcastEventObserver(context, observer)
- BroadcastReceivers.removeBroadcastEventObserver(observer)
+ public fun complicationsUserStyleSetting_with_setComplicationBounds() {
+ val complicationsStyleSetting = ComplicationsUserStyleSetting(
+ UserStyleSetting.Id("complications_style_setting"),
+ "AllComplications",
+ "Number and position",
+ icon = null,
+ complicationConfig = listOf(
+ ComplicationsOption(
+ Option.Id(RIGHT_COMPLICATION),
+ "Right",
+ null,
+ listOf(
+ ComplicationOverlay.Builder(LEFT_COMPLICATION_ID)
+ .setComplicationBounds(
+ ComplicationBounds(RectF(10f, 10f, 20f, 20f))
+ ).build()
+ )
+ )
+ ),
+ affectsWatchFaceLayers = listOf(WatchFaceLayer.COMPLICATIONS)
+ )
- // This shouldn't throw an exception.
- BroadcastReceivers.removeBroadcastEventObserver(observer)
+ // This should not crash.
+ initEngine(
+ WatchFaceType.DIGITAL,
+ listOf(leftComplication, rightComplication),
+ UserStyleSchema(listOf(complicationsStyleSetting)),
+ apiVersion = 4
+ )
}
@Suppress("DEPRECATION")
diff --git a/window/window-extensions/lint-baseline.xml b/window/window-extensions/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/window/window-extensions/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/window/window-samples/lint-baseline.xml b/window/window-samples/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/window/window-samples/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/window/window-sidecar/lint-baseline.xml b/window/window-sidecar/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/window/window-sidecar/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/window/window/api/current.txt b/window/window/api/current.txt
index 5c30487..c82eaa4 100644
--- a/window/window/api/current.txt
+++ b/window/window/api/current.txt
@@ -40,6 +40,12 @@
method public void unregisterLayoutChangeCallback(androidx.core.util.Consumer<androidx.window.WindowLayoutInfo> callback);
}
+ public interface WindowInfoRepo {
+ method public androidx.window.WindowMetrics currentWindowMetrics();
+ method public androidx.window.WindowMetrics maximumWindowMetrics();
+ method public kotlinx.coroutines.flow.Flow<androidx.window.WindowLayoutInfo> windowLayoutInfo();
+ }
+
public final class WindowLayoutInfo {
method public java.util.List<androidx.window.DisplayFeature> getDisplayFeatures();
property public final java.util.List<androidx.window.DisplayFeature> displayFeatures;
@@ -66,5 +72,8 @@
property public final android.graphics.Rect bounds;
}
+ public final class WindowServices {
+ }
+
}
diff --git a/window/window/api/public_plus_experimental_current.txt b/window/window/api/public_plus_experimental_current.txt
index 5c30487..c6788d2 100644
--- a/window/window/api/public_plus_experimental_current.txt
+++ b/window/window/api/public_plus_experimental_current.txt
@@ -40,6 +40,12 @@
method public void unregisterLayoutChangeCallback(androidx.core.util.Consumer<androidx.window.WindowLayoutInfo> callback);
}
+ public interface WindowInfoRepo {
+ method public androidx.window.WindowMetrics currentWindowMetrics();
+ method public androidx.window.WindowMetrics maximumWindowMetrics();
+ method public kotlinx.coroutines.flow.Flow<androidx.window.WindowLayoutInfo> windowLayoutInfo();
+ }
+
public final class WindowLayoutInfo {
method public java.util.List<androidx.window.DisplayFeature> getDisplayFeatures();
property public final java.util.List<androidx.window.DisplayFeature> displayFeatures;
@@ -66,5 +72,9 @@
property public final android.graphics.Rect bounds;
}
+ public final class WindowServices {
+ method @kotlinx.coroutines.ExperimentalCoroutinesApi public static androidx.window.WindowInfoRepo windowInfoRepository(android.app.Activity);
+ }
+
}
diff --git a/window/window/api/restricted_current.txt b/window/window/api/restricted_current.txt
index 5c30487..c82eaa4 100644
--- a/window/window/api/restricted_current.txt
+++ b/window/window/api/restricted_current.txt
@@ -40,6 +40,12 @@
method public void unregisterLayoutChangeCallback(androidx.core.util.Consumer<androidx.window.WindowLayoutInfo> callback);
}
+ public interface WindowInfoRepo {
+ method public androidx.window.WindowMetrics currentWindowMetrics();
+ method public androidx.window.WindowMetrics maximumWindowMetrics();
+ method public kotlinx.coroutines.flow.Flow<androidx.window.WindowLayoutInfo> windowLayoutInfo();
+ }
+
public final class WindowLayoutInfo {
method public java.util.List<androidx.window.DisplayFeature> getDisplayFeatures();
property public final java.util.List<androidx.window.DisplayFeature> displayFeatures;
@@ -66,5 +72,8 @@
property public final android.graphics.Rect bounds;
}
+ public final class WindowServices {
+ }
+
}
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 2fe4f79..cfb74ad 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -17,19 +17,9 @@
import androidx.build.LibraryGroups
import androidx.build.LibraryVersions
import androidx.build.Publish
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_CORE
-import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_EXT_JUNIT
-import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_RULES
-import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_RUNNER
-import static androidx.build.dependencies.DependenciesKt.DEXMAKER_MOCKITO
-import static androidx.build.dependencies.DependenciesKt.JUNIT
-import static androidx.build.dependencies.DependenciesKt.MOCKITO_CORE
-import static androidx.build.dependencies.DependenciesKt.MOCKITO_KOTLIN
-import static androidx.build.dependencies.DependenciesKt.ROBOLECTRIC
-import static androidx.build.dependencies.DependenciesKt.TRUTH
-import static androidx.build.dependencies.DependenciesKt.getKOTLIN_COROUTINES_ANDROID
-import static androidx.build.dependencies.DependenciesKt.getKOTLIN_STDLIB
+import static androidx.build.dependencies.DependenciesKt.*
plugins {
id("AndroidXPlugin")
@@ -38,6 +28,9 @@
}
android {
+ defaultConfig {
+ multiDexEnabled = true
+ }
buildTypes.all {
consumerProguardFiles "proguard-rules.pro"
}
@@ -69,6 +62,7 @@
testImplementation(ROBOLECTRIC)
testImplementation(MOCKITO_CORE)
testImplementation(MOCKITO_KOTLIN)
+ testImplementation(KOTLIN_COROUTINES_TEST)
testImplementation(compileOnly(project(":window:window-extensions")))
testImplementation(compileOnly(project(":window:window-sidecar")))
@@ -78,6 +72,8 @@
androidTestImplementation(DEXMAKER_MOCKITO, excludes.bytebuddy)
androidTestImplementation(MOCKITO_CORE, excludes.bytebuddy)
androidTestImplementation(MOCKITO_KOTLIN, excludes.bytebuddy)
+ androidTestImplementation(KOTLIN_COROUTINES_TEST)
+ androidTestImplementation(MULTIDEX)
androidTestImplementation(TRUTH)
androidTestImplementation(compileOnly(project(":window:window-extensions")))
androidTestImplementation(compileOnly(project(":window:window-sidecar")))
@@ -95,3 +91,10 @@
// Sidecar interface.
failOnDeprecationWarnings = false
}
+
+// Allow usage of Kotlin's @OptIn.
+tasks.withType(KotlinCompile).configureEach {
+ kotlinOptions {
+ freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn"]
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/WindowInfoRepoImpTest.kt b/window/window/src/androidTest/java/androidx/window/WindowInfoRepoImpTest.kt
new file mode 100644
index 0000000..724e6e3
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/WindowInfoRepoImpTest.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window
+
+import android.app.Activity
+import androidx.core.util.Consumer
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.runBlockingTest
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import java.util.concurrent.Executor
+
+@OptIn(ExperimentalCoroutinesApi::class)
+public class WindowInfoRepoImpTest {
+
+ @get:Rule
+ public val activityScenario: ActivityScenarioRule<TestActivity> =
+ ActivityScenarioRule(TestActivity::class.java)
+
+ private val testScope = TestCoroutineScope()
+
+ @Test
+ public fun testGetCurrentWindowMetrics() {
+ activityScenario.scenario.onActivity { testActivity ->
+ val windowBoundsHelper = WindowBoundsHelper.instance
+ val repo = WindowInfoRepoImp(
+ testActivity,
+ windowBoundsHelper,
+ FakeWindowBackend()
+ )
+ val expectedBounds = windowBoundsHelper.computeCurrentWindowBounds(testActivity)
+ val expected = WindowMetrics(expectedBounds)
+ val actual = repo.currentWindowMetrics()
+ assertEquals(expected, actual)
+ }
+ }
+
+ @Test
+ public fun testGetMaximumWindowMetrics() {
+ activityScenario.scenario.onActivity { testActivity ->
+ val windowBoundsHelper = WindowBoundsHelper.instance
+ val repo = WindowInfoRepoImp(
+ testActivity,
+ windowBoundsHelper,
+ FakeWindowBackend()
+ )
+ val expectedBounds = windowBoundsHelper.computeMaximumWindowBounds(testActivity)
+ val expected = WindowMetrics(expectedBounds)
+ val actual = repo.maximumWindowMetrics()
+ assertEquals(expected, actual)
+ }
+ }
+
+ @Test
+ public fun testWindowLayoutFeatures(): Unit = testScope.runBlockingTest {
+ activityScenario.scenario.onActivity { testActivity ->
+ val windowBoundsHelper = WindowBoundsHelper.instance
+ val fakeBackend = FakeWindowBackend()
+ val repo = WindowInfoRepoImp(
+ testActivity,
+ windowBoundsHelper,
+ fakeBackend
+ )
+ val collector = TestConsumer<WindowLayoutInfo>()
+ testScope.launch {
+ repo.windowLayoutInfo().collect(collector::accept)
+ }
+ fakeBackend.triggerSignal(WindowLayoutInfo(emptyList()))
+ collector.assertValue(WindowLayoutInfo(emptyList()))
+ }
+ }
+
+ private class FakeWindowBackend : WindowBackend {
+
+ private class CallbackHolder(
+ val executor: Executor,
+ val callback: Consumer<WindowLayoutInfo>
+ ) : Consumer<WindowLayoutInfo> {
+
+ override fun accept(t: WindowLayoutInfo?) {
+ executor.execute { callback.accept(t) }
+ }
+ }
+
+ private val consumers = mutableListOf<CallbackHolder>()
+
+ fun triggerSignal(info: WindowLayoutInfo) {
+ consumers.forEach { consumer -> consumer.accept(info) }
+ }
+
+ override fun registerLayoutChangeCallback(
+ activity: Activity,
+ executor: Executor,
+ callback: Consumer<WindowLayoutInfo>
+ ) {
+ consumers.add(CallbackHolder(executor, callback))
+ }
+
+ override fun unregisterLayoutChangeCallback(callback: Consumer<WindowLayoutInfo>) {
+ consumers.removeIf { it.callback == callback }
+ }
+ }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/WindowInfoRepo.kt b/window/window/src/main/java/androidx/window/WindowInfoRepo.kt
new file mode 100644
index 0000000..32ea8e3
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/WindowInfoRepo.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window
+
+import android.content.Context
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * An interface to provide all the relevant info about a [android.view.Window].
+ */
+public interface WindowInfoRepo {
+
+ /**
+ * Returns the [WindowMetrics] according to the current system state.
+ *
+ *
+ * The metrics describe the size of the area the window would occupy with
+ * [MATCH_PARENT][android.view.WindowManager.LayoutParams.MATCH_PARENT] width and height
+ * and any combination of flags that would allow the window to extend behind display cutouts.
+ *
+ *
+ * The value of this is based on the **current** windowing state of the system. For
+ * example, for activities in multi-window mode, the metrics returned are based on the
+ * current bounds that the user has selected for the [Activity][android.app.Activity]'s
+ * window.
+ *
+ * @see maximumWindowMetrics
+ * @see android.view.WindowManager.getCurrentWindowMetrics
+ */
+ public fun currentWindowMetrics(): WindowMetrics
+
+ /**
+ * Returns the largest [WindowMetrics] an app may expect in the current system state.
+ *
+ *
+ * The metrics describe the size of the largest potential area the window might occupy with
+ * [MATCH_PARENT][android.view.WindowManager.LayoutParams.MATCH_PARENT] width and height
+ * and any combination of flags that would allow the window to extend behind display cutouts.
+ *
+ *
+ * The value of this is based on the largest **potential** windowing state of the system.
+ * For example, for activities in multi-window mode the metrics returned are based on what the
+ * bounds would be if the user expanded the window to cover the entire screen.
+ *
+ *
+ * Note that this might still be smaller than the size of the physical display if certain
+ * areas of the display are not available to windows created for the associated [Context].
+ * For example, devices with foldable displays that wrap around the enclosure may split the
+ * physical display into different regions, one for the front and one for the back, each acting
+ * as different logical displays. In this case [.getMaximumWindowMetrics] would return
+ * the region describing the side of the device the associated [context's][Context]
+ * window is placed.
+ *
+ * @see currentWindowMetrics
+ * @see android.view.WindowManager.getMaximumWindowMetrics
+ */
+ public fun maximumWindowMetrics(): WindowMetrics
+
+ /**
+ * A [Flow] of [WindowLayoutInfo] that contains all the available features.
+ */
+ public fun windowLayoutInfo(): Flow<WindowLayoutInfo>
+}
diff --git a/window/window/src/main/java/androidx/window/WindowInfoRepoImp.kt b/window/window/src/main/java/androidx/window/WindowInfoRepoImp.kt
new file mode 100644
index 0000000..817459f
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/WindowInfoRepoImp.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window
+
+import android.app.Activity
+import android.content.Context
+import androidx.core.util.Consumer
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.buffer
+import kotlinx.coroutines.flow.callbackFlow
+
+/**
+ * An implementation of [WindowInfoRepo] that provides the [WindowLayoutInfo] and
+ * [WindowMetrics] for the given [Activity].
+ *
+ * @param activity that the provided window is based on.
+ * @param windowBoundsHelper a helper to calculate the [WindowMetrics] for the [Activity].
+ * @param windowBackend a helper to provide the [WindowLayoutInfo].
+ */
+@ExperimentalCoroutinesApi
+internal class WindowInfoRepoImp(
+ private val activity: Activity,
+ private val windowBoundsHelper: WindowBoundsHelper,
+ private val windowBackend: WindowBackend
+) : WindowInfoRepo {
+
+ /**
+ * Returns the [WindowMetrics] according to the current system state.
+ *
+ *
+ * The metrics describe the size of the area the window would occupy with
+ * [MATCH_PARENT][android.view.WindowManager.LayoutParams.MATCH_PARENT] width and height
+ * and any combination of flags that would allow the window to extend behind display cutouts.
+ *
+ *
+ * The value of this is based on the **current** windowing state of the system. For
+ * example, for activities in multi-window mode, the metrics returned are based on the
+ * current bounds that the user has selected for the [Activity][android.app.Activity]'s
+ * window.
+ *
+ * @see maximumWindowMetrics
+ * @see android.view.WindowManager.getCurrentWindowMetrics
+ */
+ override fun currentWindowMetrics(): WindowMetrics {
+ return WindowMetrics(windowBoundsHelper.computeCurrentWindowBounds(activity))
+ }
+
+ /**
+ * Returns the largest [WindowMetrics] an app may expect in the current system state.
+ *
+ *
+ * The metrics describe the size of the largest potential area the window might occupy with
+ * [MATCH_PARENT][android.view.WindowManager.LayoutParams.MATCH_PARENT] width and height
+ * and any combination of flags that would allow the window to extend behind display cutouts.
+ *
+ *
+ * The value of this is based on the largest **potential** windowing state of the system.
+ * For example, for activities in multi-window mode the metrics returned are based on what the
+ * bounds would be if the user expanded the window to cover the entire screen.
+ *
+ *
+ * Note that this might still be smaller than the size of the physical display if certain
+ * areas of the display are not available to windows created for the associated [Context].
+ * For example, devices with foldable displays that wrap around the enclosure may split the
+ * physical display into different regions, one for the front and one for the back, each acting
+ * as different logical displays. In this case [.getMaximumWindowMetrics] would return
+ * the region describing the side of the device the associated [context's][Context]
+ * window is placed.
+ *
+ * @see currentWindowMetrics
+ * @see android.view.WindowManager.getMaximumWindowMetrics
+ */
+ override fun maximumWindowMetrics(): WindowMetrics {
+ return WindowMetrics(windowBoundsHelper.computeMaximumWindowBounds(activity))
+ }
+
+ /**
+ * A [Flow] of window layout changes in the current visual [Context].
+ *
+ * @see Activity.onAttachedToWindow
+ */
+ override fun windowLayoutInfo(): Flow<WindowLayoutInfo> = callbackFlow {
+ val callback = Consumer<WindowLayoutInfo> { info -> offer(info) }
+ windowBackend.registerLayoutChangeCallback(activity, Runnable::run, callback)
+ awaitClose { windowBackend.unregisterLayoutChangeCallback(callback) }
+ }.buffer(capacity = UNLIMITED)
+}
diff --git a/window/window/src/main/java/androidx/window/WindowServices.kt b/window/window/src/main/java/androidx/window/WindowServices.kt
new file mode 100644
index 0000000..fd3881d
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/WindowServices.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:JvmName("WindowServices")
+
+package androidx.window
+
+import android.app.Activity
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+/**
+ * Provide an instance of [WindowInfoRepo] that is associated to the given [Activity]
+ */
+@ExperimentalCoroutinesApi
+public fun Activity.windowInfoRepository(): WindowInfoRepo {
+ return WindowInfoRepoImp(
+ this,
+ WindowBoundsHelper.instance,
+ ExtensionWindowBackend.getInstance(this)
+ )
+}
diff --git a/window/window/src/testUtil/java/androidx/window/TestConsumer.kt b/window/window/src/testUtil/java/androidx/window/TestConsumer.kt
new file mode 100644
index 0000000..6976014
--- /dev/null
+++ b/window/window/src/testUtil/java/androidx/window/TestConsumer.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window
+
+import androidx.core.util.Consumer
+import org.junit.Assert.assertEquals
+
+/**
+ * A test [Consumer] to hold all the values and make assertions based on the values.
+ */
+public class TestConsumer<T> : Consumer<T> {
+
+ private val values: MutableList<T> = mutableListOf()
+
+ /**
+ * Add the value to the list of seen values.
+ */
+ override fun accept(t: T) {
+ values.add(t)
+ }
+
+ /**
+ * Assert that there have been a fixed number of values
+ */
+ public fun assertValueCount(count: Int) {
+ assertEquals(count, values.size)
+ }
+
+ /**
+ * Assert that there has been exactly one value.
+ */
+ public fun assertValue(t: T) {
+ assertValueCount(1)
+ assertEquals(t, values[0])
+ }
+}
diff --git a/work/workmanager-benchmark/lint-baseline.xml b/work/workmanager-benchmark/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/work/workmanager-benchmark/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/work/workmanager-inspection/lint-baseline.xml b/work/workmanager-inspection/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/work/workmanager-inspection/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/work/workmanager-ktx/lint-baseline.xml b/work/workmanager-ktx/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/work/workmanager-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/work/workmanager-lint/lint-baseline.xml b/work/workmanager-lint/lint-baseline.xml
deleted file mode 100644
index 8794ae8..0000000
--- a/work/workmanager-lint/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" version="4.2.0-beta06">
-
-</issues>
diff --git a/work/workmanager-multiprocess/lint-baseline.xml b/work/workmanager-multiprocess/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/work/workmanager-multiprocess/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/work/workmanager-rxjava2/lint-baseline.xml b/work/workmanager-rxjava2/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/work/workmanager-rxjava2/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>
diff --git a/work/workmanager-rxjava3/lint-baseline.xml b/work/workmanager-rxjava3/lint-baseline.xml
deleted file mode 100644
index aaebb86..0000000
--- a/work/workmanager-rxjava3/lint-baseline.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.2.0-beta06" client="gradle" variant="debug" version="4.2.0-beta06">
-
-</issues>