From 63fc5a5c12ecffbbbcc3d3d243c6d6e0f2172392 Mon Sep 17 00:00:00 2001 From: Rick Busarow Date: Thu, 13 Jul 2023 12:28:20 -0500 Subject: [PATCH 1/2] Cache the AVD in CI before executing any tests background: https://workflow-community.slack.com/archives/CHTFPR277/p1689193974005269 I was using `actions/cache@v3` to restore and possibly save the AVD in instrumented test shards. That basic "cache" action handles both reading and writing to the cache. The writing is done during a post-action, meaning that if the AVD was cached, it was cached *after* it had been used for the instrumented tests. Now, we use the newer `actions/cache/restore@v3` and `actions/cache/save@v3` actions, like we use elsewhere. Now, if there was a cache miss and we have to make a new AVD, it is cached before the tests are executed so that it doesn't have any of our test apps installed. --- .../gradle-tasks-with-emulator/action.yml | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/.github/actions/gradle-tasks-with-emulator/action.yml b/.github/actions/gradle-tasks-with-emulator/action.yml index ef628fc4e..21f7183f0 100644 --- a/.github/actions/gradle-tasks-with-emulator/action.yml +++ b/.github/actions/gradle-tasks-with-emulator/action.yml @@ -1,13 +1,13 @@ name : Run Android Instrumentation Tests with Artifact and AVD Caching -description: This action sets up Gradle, runs a preparatory task, runs Android tests on an emulator, and uploads test results. +description : This action sets up Gradle, runs a preparatory task, runs Android tests on an emulator, and uploads test results. -inputs: - prepare-task: - description: 'Gradle task for preparing necessary artifacts. Supports multi-line input.' - required: true - test-task: - description: 'Gradle task for running instrumentation tests. Supports multi-line input.' - required: true +inputs : + prepare-task : + description : 'Gradle task for preparing necessary artifacts. Supports multi-line input.' + required : true + test-task : + description : 'Gradle task for running instrumentation tests. Supports multi-line input.' + required : true api-level : description : 'The Android SDK api level, like `29`' required : true @@ -43,40 +43,51 @@ runs : write-cache-key : ${{ inputs.write-cache-key }} # Get the AVD if it's already cached. - - name: AVD cache - uses: actions/cache@v3 - id: avd-cache - with: - path: | + - name : AVD cache + uses : actions/cache/restore@v3 + id : restore-avd-cache + with : + path : | ~/.android/avd/* ~/.android/adb* - key: avd-${{ matrix.api-level }} + key : avd-${{ matrix.api-level }} - # If the AVD cache didn't exist, create an AVD and cache it. - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ inputs.api-level }} + # If the AVD cache didn't exist, create an AVD + - name : create AVD and generate snapshot for caching + if : steps.restore-avd-cache.outputs.cache-hit != 'true' + uses : reactivecircus/android-emulator-runner@v2 + with : + api-level : ${{ inputs.api-level }} arch : x86_64 - disable-animations: false - emulator-boot-timeout: 12000 - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - force-avd-creation: false + disable-animations : false + emulator-boot-timeout : 12000 + emulator-options : -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + force-avd-creation : false profile : Galaxy Nexus - ram-size: 4096M - script: echo "Generated AVD snapshot." + ram-size : 4096M + script : echo "Generated AVD snapshot." + + # If we just created an AVD because there wasn't one in the cache, then cache that AVD. + - name : cache new AVD before tests + if : steps.restore-avd-cache.outputs.cache-hit != 'true' + id : save-avd-cache + uses : actions/cache/save@v3 + with : + path : | + ~/.android/avd/* + ~/.android/adb* + key : avd-${{ matrix.api-level }} # Run the actual emulator tests. # At this point every task should be up-to-date and the AVD should be ready to go. - - name: run tests - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: ${{ inputs.api-level }} + - name : run tests + uses : reactivecircus/android-emulator-runner@v2 + with : + api-level : ${{ inputs.api-level }} arch : x86_64 - disable-animations: true - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - force-avd-creation: false + disable-animations : true + emulator-options : -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + force-avd-creation : false profile : Galaxy Nexus script : ./gradlew ${{ inputs.test-task }} From 638c209535dd3daeef4775de823d3c2e2c43e201 Mon Sep 17 00:00:00 2001 From: Stephen Edwards Date: Wed, 12 Jul 2023 14:24:18 -0400 Subject: [PATCH 2/2] Update AndroidX Dependencies --- gradle/libs.versions.toml | 6 ++-- .../dependencies/releaseRuntimeClasspath.txt | 34 ++++++++++--------- .../dependencies/releaseRuntimeClasspath.txt | 34 ++++++++++--------- .../ui/compose/LegacyWorkflowRenderingTest.kt | 10 +++--- .../ui/compose/WorkflowRenderingTest.kt | 11 +++--- .../ui/compose/LegacyWorkflowRendering.kt | 9 ++--- .../workflow1/ui/compose/WorkflowRendering.kt | 7 ++-- .../dependencies/releaseRuntimeClasspath.txt | 30 ++++++++-------- .../dependencies/releaseRuntimeClasspath.txt | 30 +++++++++------- .../workflow1/ui/BackPressedHandlerTest.kt | 10 ++++-- .../ui/WorkflowViewStubLifecycleTest.kt | 3 +- .../ui/container/ViewStateCacheTest.kt | 4 ++- .../squareup/workflow1/ui/BackPressHandler.kt | 4 +-- .../squareup/workflow1/ui/ViewBackHandler.kt | 4 +-- .../workflow1/ui/ViewLaunchWhenAttached.kt | 4 +-- .../ui/androidx/WorkflowAndroidXSupport.kt | 8 ++--- .../ui/androidx/WorkflowLifecycleOwner.kt | 28 ++++++++------- .../WorkflowSavedStateRegistryAggregator.kt | 8 ++--- .../workflow1/ui/container/DialogSession.kt | 4 +-- .../ui/container/LayeredDialogSessions.kt | 12 +++---- .../workflow1/ui/container/ViewStateCache.kt | 2 +- .../ui/ViewLaunchWhenAttachedTest.kt | 8 ++--- .../RealWorkflowLifecycleOwnerTest.kt | 4 +-- ...orkflowSavedStateRegistryAggregatorTest.kt | 6 ++-- .../test/AbstractLifecycleTestActivity.kt | 6 ++-- .../dependencies/releaseRuntimeClasspath.txt | 30 +++++++++------- 26 files changed, 173 insertions(+), 143 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 97d58a251..06fb5abd7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,10 +14,10 @@ androidx-compose-compiler = "1.4.4" # see https://developer.android.com/jetpack/compose/bom/bom-mapping androidx-compose-bom = "2023.01.00" androidx-constraintlayout = "2.1.4" -androidx-core = "1.6.0" +androidx-core = "1.10.0" androidx-fragment = "1.3.6" androidx-gridlayout = "1.0.0" -androidx-lifecycle = "2.5.1" +androidx-lifecycle = "2.6.1" androidx-navigation = "2.4.0-alpha09" androidx-paging = "3.0.1" androidx-profileinstaller = "1.2.0-alpha02" @@ -33,7 +33,7 @@ androidx-test-truth-ext = "1.5.0" androidx-tracing = "1.1.0" androidx-transition = "1.4.1" androidx-viewbinding = "4.2.1" -androidx-work = "2.6.0" +androidx-work = "2.7.0" detekt = "1.19.0" dokka = "1.8.20" diff --git a/workflow-ui/compose-tooling/dependencies/releaseRuntimeClasspath.txt b/workflow-ui/compose-tooling/dependencies/releaseRuntimeClasspath.txt index 628e5d974..da1efde2f 100644 --- a/workflow-ui/compose-tooling/dependencies/releaseRuntimeClasspath.txt +++ b/workflow-ui/compose-tooling/dependencies/releaseRuntimeClasspath.txt @@ -1,10 +1,11 @@ androidx.activity:activity-compose:1.6.1 androidx.activity:activity-ktx:1.6.1 androidx.activity:activity:1.6.1 -androidx.annotation:annotation-experimental:1.1.0 -androidx.annotation:annotation:1.5.0 -androidx.arch.core:core-common:2.1.0 -androidx.arch.core:core-runtime:2.1.0 +androidx.annotation:annotation-experimental:1.3.0 +androidx.annotation:annotation-jvm:1.6.0 +androidx.annotation:annotation:1.6.0 +androidx.arch.core:core-common:2.2.0 +androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.collection:collection:1.1.0 androidx.compose.animation:animation-core:1.3.3 @@ -21,19 +22,20 @@ androidx.compose.ui:ui-unit:1.3.3 androidx.compose.ui:ui-util:1.3.3 androidx.compose.ui:ui:1.3.3 androidx.compose:compose-bom:2023.01.00 -androidx.concurrent:concurrent-futures:1.0.0 -androidx.core:core-ktx:1.6.0 -androidx.core:core:1.8.0 +androidx.concurrent:concurrent-futures:1.1.0 +androidx.core:core-ktx:1.10.0 +androidx.core:core:1.10.0 androidx.customview:customview-poolingcontainer:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.5.1 -androidx.lifecycle:lifecycle-common:2.5.1 -androidx.lifecycle:lifecycle-livedata-core:2.5.1 -androidx.lifecycle:lifecycle-runtime-ktx:2.5.1 -androidx.lifecycle:lifecycle-runtime:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1 -androidx.lifecycle:lifecycle-viewmodel:2.5.1 -androidx.profileinstaller:profileinstaller:1.2.0 +androidx.interpolator:interpolator:1.0.0 +androidx.lifecycle:lifecycle-common-java8:2.6.1 +androidx.lifecycle:lifecycle-common:2.6.1 +androidx.lifecycle:lifecycle-livedata-core:2.6.1 +androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 +androidx.lifecycle:lifecycle-runtime:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 +androidx.lifecycle:lifecycle-viewmodel:2.6.1 +androidx.profileinstaller:profileinstaller:1.3.0 androidx.savedstate:savedstate-ktx:1.2.1 androidx.savedstate:savedstate:1.2.1 androidx.startup:startup-runtime:1.1.1 diff --git a/workflow-ui/compose/dependencies/releaseRuntimeClasspath.txt b/workflow-ui/compose/dependencies/releaseRuntimeClasspath.txt index 0cc2b7342..f68ab6bf0 100644 --- a/workflow-ui/compose/dependencies/releaseRuntimeClasspath.txt +++ b/workflow-ui/compose/dependencies/releaseRuntimeClasspath.txt @@ -1,10 +1,11 @@ androidx.activity:activity-compose:1.6.1 androidx.activity:activity-ktx:1.6.1 androidx.activity:activity:1.6.1 -androidx.annotation:annotation-experimental:1.1.0 -androidx.annotation:annotation:1.5.0 -androidx.arch.core:core-common:2.1.0 -androidx.arch.core:core-runtime:2.1.0 +androidx.annotation:annotation-experimental:1.3.0 +androidx.annotation:annotation-jvm:1.6.0 +androidx.annotation:annotation:1.6.0 +androidx.arch.core:core-common:2.2.0 +androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.collection:collection:1.1.0 androidx.compose.animation:animation-core:1.3.3 @@ -18,19 +19,20 @@ androidx.compose.ui:ui-unit:1.3.3 androidx.compose.ui:ui-util:1.3.3 androidx.compose.ui:ui:1.3.3 androidx.compose:compose-bom:2023.01.00 -androidx.concurrent:concurrent-futures:1.0.0 -androidx.core:core-ktx:1.6.0 -androidx.core:core:1.8.0 +androidx.concurrent:concurrent-futures:1.1.0 +androidx.core:core-ktx:1.10.0 +androidx.core:core:1.10.0 androidx.customview:customview-poolingcontainer:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.5.1 -androidx.lifecycle:lifecycle-common:2.5.1 -androidx.lifecycle:lifecycle-livedata-core:2.5.1 -androidx.lifecycle:lifecycle-runtime-ktx:2.5.1 -androidx.lifecycle:lifecycle-runtime:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1 -androidx.lifecycle:lifecycle-viewmodel:2.5.1 -androidx.profileinstaller:profileinstaller:1.2.0 +androidx.interpolator:interpolator:1.0.0 +androidx.lifecycle:lifecycle-common-java8:2.6.1 +androidx.lifecycle:lifecycle-common:2.6.1 +androidx.lifecycle:lifecycle-livedata-core:2.6.1 +androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 +androidx.lifecycle:lifecycle-runtime:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 +androidx.lifecycle:lifecycle-viewmodel:2.6.1 +androidx.profileinstaller:profileinstaller:1.3.0 androidx.savedstate:savedstate-ktx:1.2.1 androidx.savedstate:savedstate:1.2.1 androidx.startup:startup-runtime:1.1.1 diff --git a/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRenderingTest.kt b/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRenderingTest.kt index 89e5a36f1..70320e829 100644 --- a/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRenderingTest.kt +++ b/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRenderingTest.kt @@ -50,7 +50,7 @@ import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed @@ -239,7 +239,7 @@ internal class LegacyWorkflowRenderingTest { override fun onAttachedToWindow() { super.onAttachedToWindow() - val lifecycle = ViewTreeLifecycleOwner.get(this)!!.lifecycle + val lifecycle = this.findViewTreeLifecycleOwner()!!.lifecycle lifecycle.addObserver( LifecycleEventObserver { _, event -> lifecycleEvents += event @@ -277,7 +277,8 @@ internal class LegacyWorkflowRenderingTest { val states = mutableListOf() val parentOwner = object : LifecycleOwner { val registry = LifecycleRegistry(this) - override fun getLifecycle(): Lifecycle = registry + override val lifecycle: Lifecycle + get() = registry } composeRule.setContent { @@ -319,7 +320,8 @@ internal class LegacyWorkflowRenderingTest { val states = mutableListOf() val parentOwner = object : LifecycleOwner { val registry = LifecycleRegistry(this) - override fun getLifecycle(): Lifecycle = registry + override val lifecycle: Lifecycle + get() = registry } composeRule.runOnIdle { // Cannot go directly to DESTROYED diff --git a/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/WorkflowRenderingTest.kt b/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/WorkflowRenderingTest.kt index 75084a80b..107ed58f5 100644 --- a/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/WorkflowRenderingTest.kt +++ b/workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/WorkflowRenderingTest.kt @@ -48,7 +48,7 @@ import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed @@ -236,7 +236,7 @@ internal class WorkflowRenderingTest { val view = object : View(context) { override fun onAttachedToWindow() { super.onAttachedToWindow() - val lifecycle = ViewTreeLifecycleOwner.get(this)!!.lifecycle + val lifecycle = this.findViewTreeLifecycleOwner()!!.lifecycle lifecycle.addObserver( LifecycleEventObserver { _, event -> lifecycleEvents += event } ) @@ -273,7 +273,8 @@ internal class WorkflowRenderingTest { val states = mutableListOf() val parentOwner = object : LifecycleOwner { val registry = LifecycleRegistry(this) - override fun getLifecycle(): Lifecycle = registry + override val lifecycle: Lifecycle + get() = registry } composeRule.setContent { @@ -315,7 +316,8 @@ internal class WorkflowRenderingTest { val states = mutableListOf() val parentOwner = object : LifecycleOwner { val registry = LifecycleRegistry(this) - override fun getLifecycle(): Lifecycle = registry + override val lifecycle: Lifecycle + get() = registry } composeRule.runOnIdle { // Cannot go directly to DESTROYED @@ -533,7 +535,6 @@ internal class WorkflowRenderingTest { } } - @Suppress("UNCHECKED_CAST") private interface ComposableRendering> : AndroidScreen { diff --git a/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRendering.kt b/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRendering.kt index fcc63ebf9..3226a5529 100644 --- a/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRendering.kt +++ b/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/LegacyWorkflowRendering.kt @@ -18,7 +18,7 @@ import androidx.lifecycle.Lifecycle.State.INITIALIZED import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.setViewTreeLifecycleOwner import com.squareup.workflow1.ui.Compatible import com.squareup.workflow1.ui.ViewEnvironment import com.squareup.workflow1.ui.ViewFactory @@ -90,7 +90,8 @@ public fun WorkflowRendering( val lifecycleOwner = remember { object : LifecycleOwner { val registry = LifecycleRegistry(this) - override fun getLifecycle(): Lifecycle = registry + override val lifecycle: Lifecycle + get() = registry } } val parentLifecycle = LocalLifecycleOwner.current.lifecycle @@ -107,7 +108,7 @@ public fun WorkflowRendering( // If we're leaving the composition it means the WorkflowRendering is either going away itself // or about to switch to an incompatible rendering – either way, this lifecycle is dead. Note - // that we can't transition from INITIALIZED to DESTROYED – the LifecycelRegistry will throw. + // that we can't transition from INITIALIZED to DESTROYED – the LifecycleRegistry will throw. // WorkflowLifecycleOwner has this same check. if (lifecycleOwner.registry.currentState != INITIALIZED) { lifecycleOwner.registry.currentState = DESTROYED @@ -168,7 +169,7 @@ private fun ViewFactory.asComposeViewFactory() = } // Unfortunately AndroidView doesn't propagate this itself. - ViewTreeLifecycleOwner.set(view, lifecycleOwner) + view.setViewTreeLifecycleOwner(lifecycleOwner) // We don't propagate the (non-compose) SavedStateRegistryOwner, or the (compose) // SaveableStateRegistry, because currently all our navigation is implemented as // Android views, which ensures there is always an Android view between any state diff --git a/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/WorkflowRendering.kt b/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/WorkflowRendering.kt index 891c148f2..9f6ab9000 100644 --- a/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/WorkflowRendering.kt +++ b/workflow-ui/compose/src/main/java/com/squareup/workflow1/ui/compose/WorkflowRendering.kt @@ -21,7 +21,7 @@ import androidx.lifecycle.Lifecycle.State.INITIALIZED import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.setViewTreeLifecycleOwner import com.squareup.workflow1.ui.Compatible import com.squareup.workflow1.ui.OnBackPressedDispatcherOwnerKey import com.squareup.workflow1.ui.Screen @@ -123,7 +123,8 @@ public fun WorkflowRendering( val lifecycleOwner = remember { object : LifecycleOwner { val registry = LifecycleRegistry(this) - override fun getLifecycle(): Lifecycle = registry + override val lifecycle: Lifecycle + get() = registry } } val parentLifecycle = LocalLifecycleOwner.current.lifecycle @@ -213,7 +214,7 @@ private fun ScreenViewFactory.asComposeViewFactory() viewHolder.view.setTag(R.id.workflow_screen_view_holder, viewHolder) // Unfortunately AndroidView doesn't propagate these itself. - ViewTreeLifecycleOwner.set(viewHolder.view, lifecycleOwner) + viewHolder.view.setViewTreeLifecycleOwner(lifecycleOwner) onBackOrNull?.let { viewHolder.view.setViewTreeOnBackPressedDispatcherOwner(it) } diff --git a/workflow-ui/container-android/dependencies/releaseRuntimeClasspath.txt b/workflow-ui/container-android/dependencies/releaseRuntimeClasspath.txt index 53130e672..f77cb5b9d 100644 --- a/workflow-ui/container-android/dependencies/releaseRuntimeClasspath.txt +++ b/workflow-ui/container-android/dependencies/releaseRuntimeClasspath.txt @@ -1,14 +1,15 @@ androidx.activity:activity:1.6.1 androidx.annotation:annotation-experimental:1.3.0 -androidx.annotation:annotation:1.3.0 +androidx.annotation:annotation-jvm:1.6.0 +androidx.annotation:annotation:1.6.0 androidx.appcompat:appcompat-resources:1.6.1 androidx.appcompat:appcompat:1.6.1 -androidx.arch.core:core-common:2.1.0 -androidx.arch.core:core-runtime:2.1.0 +androidx.arch.core:core-common:2.2.0 +androidx.arch.core:core-runtime:2.2.0 androidx.collection:collection:1.1.0 -androidx.concurrent:concurrent-futures:1.0.0 -androidx.core:core-ktx:1.9.0 -androidx.core:core:1.9.0 +androidx.concurrent:concurrent-futures:1.1.0 +androidx.core:core-ktx:1.10.0 +androidx.core:core:1.10.0 androidx.cursoradapter:cursoradapter:1.0.0 androidx.customview:customview:1.0.0 androidx.drawerlayout:drawerlayout:1.0.0 @@ -16,15 +17,16 @@ androidx.emoji2:emoji2-views-helper:1.2.0 androidx.emoji2:emoji2:1.2.0 androidx.fragment:fragment:1.3.6 androidx.interpolator:interpolator:1.0.0 -androidx.lifecycle:lifecycle-common:2.5.1 -androidx.lifecycle:lifecycle-livedata-core:2.5.1 -androidx.lifecycle:lifecycle-livedata:2.5.1 -androidx.lifecycle:lifecycle-process:2.5.1 -androidx.lifecycle:lifecycle-runtime-ktx:2.5.1 -androidx.lifecycle:lifecycle-runtime:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1 -androidx.lifecycle:lifecycle-viewmodel:2.5.1 +androidx.lifecycle:lifecycle-common:2.6.1 +androidx.lifecycle:lifecycle-livedata-core:2.6.1 +androidx.lifecycle:lifecycle-livedata:2.6.1 +androidx.lifecycle:lifecycle-process:2.6.1 +androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 +androidx.lifecycle:lifecycle-runtime:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 +androidx.lifecycle:lifecycle-viewmodel:2.6.1 androidx.loader:loader:1.0.0 +androidx.profileinstaller:profileinstaller:1.3.0 androidx.resourceinspection:resourceinspection-annotation:1.0.1 androidx.savedstate:savedstate:1.2.1 androidx.startup:startup-runtime:1.1.1 diff --git a/workflow-ui/core-android/dependencies/releaseRuntimeClasspath.txt b/workflow-ui/core-android/dependencies/releaseRuntimeClasspath.txt index 4612d1cca..ee0ffdad2 100644 --- a/workflow-ui/core-android/dependencies/releaseRuntimeClasspath.txt +++ b/workflow-ui/core-android/dependencies/releaseRuntimeClasspath.txt @@ -1,19 +1,23 @@ androidx.activity:activity:1.6.1 -androidx.annotation:annotation-experimental:1.1.0 -androidx.annotation:annotation:1.2.0 -androidx.arch.core:core-common:2.1.0 -androidx.arch.core:core-runtime:2.1.0 +androidx.annotation:annotation-experimental:1.3.0 +androidx.annotation:annotation-jvm:1.6.0 +androidx.annotation:annotation:1.6.0 +androidx.arch.core:core-common:2.2.0 +androidx.arch.core:core-runtime:2.2.0 androidx.collection:collection:1.1.0 -androidx.concurrent:concurrent-futures:1.0.0 -androidx.core:core-ktx:1.6.0 -androidx.core:core:1.8.0 -androidx.lifecycle:lifecycle-common:2.5.1 -androidx.lifecycle:lifecycle-livedata-core:2.5.1 -androidx.lifecycle:lifecycle-runtime-ktx:2.5.1 -androidx.lifecycle:lifecycle-runtime:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1 -androidx.lifecycle:lifecycle-viewmodel:2.5.1 +androidx.concurrent:concurrent-futures:1.1.0 +androidx.core:core-ktx:1.10.0 +androidx.core:core:1.10.0 +androidx.interpolator:interpolator:1.0.0 +androidx.lifecycle:lifecycle-common:2.6.1 +androidx.lifecycle:lifecycle-livedata-core:2.6.1 +androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 +androidx.lifecycle:lifecycle-runtime:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 +androidx.lifecycle:lifecycle-viewmodel:2.6.1 +androidx.profileinstaller:profileinstaller:1.3.0 androidx.savedstate:savedstate:1.2.1 +androidx.startup:startup-runtime:1.1.1 androidx.tracing:tracing:1.0.0 androidx.transition:transition:1.4.1 androidx.versionedparcelable:versionedparcelable:1.1.1 diff --git a/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/BackPressedHandlerTest.kt b/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/BackPressedHandlerTest.kt index 42bc760d4..b672850df 100644 --- a/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/BackPressedHandlerTest.kt +++ b/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/BackPressedHandlerTest.kt @@ -7,10 +7,12 @@ import android.view.ViewGroup import androidx.activity.ComponentActivity import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedDispatcherSpy +import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle.State.DESTROYED import androidx.lifecycle.Lifecycle.State.RESUMED +import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.setViewTreeLifecycleOwner import androidx.test.ext.junit.rules.ActivityScenarioRule import com.google.common.truth.Truth.assertThat import com.squareup.workflow1.ui.internal.test.IdlingDispatcherRule @@ -106,7 +108,11 @@ internal class BackPressedHandlerTest { view.backPressedHandler = viewBackHandler assertThat(spy.callbacks()).hasSize(1) - ViewTreeLifecycleOwner.set(view) { lifecycle } + val lifecycleOwner = object : LifecycleOwner { + override val lifecycle: Lifecycle + get() = lifecycle + } + view.setViewTreeLifecycleOwner(lifecycleOwner) activity.setContentView(view) (view.parent as ViewGroup).removeView(view) diff --git a/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/WorkflowViewStubLifecycleTest.kt b/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/WorkflowViewStubLifecycleTest.kt index 6a8074100..21d516d48 100644 --- a/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/WorkflowViewStubLifecycleTest.kt +++ b/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/WorkflowViewStubLifecycleTest.kt @@ -262,7 +262,8 @@ internal class WorkflowViewStubLifecycleTest { override val savedStateRegistry: SavedStateRegistry get() = controller.savedStateRegistry - override fun getLifecycle(): Lifecycle = lifecycleRegistry + override val lifecycle: Lifecycle + get() = lifecycleRegistry } data class RegistrySetter(val wrapped: TestRendering) : ViewRendering() { diff --git a/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/container/ViewStateCacheTest.kt b/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/container/ViewStateCacheTest.kt index f3391b54a..120feb525 100644 --- a/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/container/ViewStateCacheTest.kt +++ b/workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/container/ViewStateCacheTest.kt @@ -36,7 +36,9 @@ internal class ViewStateCacheTest { private val viewEnvironment = EMPTY private val fakeOnBack = object : OnBackPressedDispatcherOwner { - override fun getLifecycle(): Lifecycle = error("") + override val lifecycle: Lifecycle + get() = error("") + override fun getOnBackPressedDispatcher(): OnBackPressedDispatcher = error("") } diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/BackPressHandler.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/BackPressHandler.kt index b15fbf691..3386b28bf 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/BackPressHandler.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/BackPressHandler.kt @@ -6,7 +6,7 @@ import androidx.activity.OnBackPressedCallback import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import com.squareup.workflow1.ui.androidx.WorkflowAndroidXSupport.onBackPressedDispatcherOwnerOrNull /** @@ -108,7 +108,7 @@ private class AttachStateAndLifecycleObserver( lifecycle.removeObserver(this) lifecycleOrNull = null } - ViewTreeLifecycleOwner.get(view)?.lifecycle?.let { lifecycle -> + view.findViewTreeLifecycleOwner()?.lifecycle?.let { lifecycle -> lifecycleOrNull = lifecycle onBackPressedCallback.handlerOrNull = handler onBackPressedCallback.isEnabled = true diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewBackHandler.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewBackHandler.kt index cfe2cee40..eb11f0f71 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewBackHandler.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewBackHandler.kt @@ -2,7 +2,7 @@ package com.squareup.workflow1.ui import android.view.View import androidx.activity.OnBackPressedCallback -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import com.squareup.workflow1.ui.androidx.WorkflowAndroidXSupport.onBackPressedDispatcherOwnerOrNull /** @@ -28,7 +28,7 @@ public fun View.setBackHandler( val dispatcher = requireNotNull(onBackPressedDispatcherOwnerOrNull()?.onBackPressedDispatcher) { "Unable to find a onBackPressedDispatcherOwner for ${this@setBackHandler}." } - val lifecycleOwner = requireNotNull(ViewTreeLifecycleOwner.get(this@setBackHandler)) { + val lifecycleOwner = requireNotNull(this@setBackHandler.findViewTreeLifecycleOwner()) { "Unable to find a ViewTreeLifecycleOwner for ${this@setBackHandler}." } diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewLaunchWhenAttached.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewLaunchWhenAttached.kt index d66f19749..9212bc742 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewLaunchWhenAttached.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/ViewLaunchWhenAttached.kt @@ -3,7 +3,7 @@ package com.squareup.workflow1.ui import android.content.res.Resources.NotFoundException import android.view.View import android.view.View.NO_ID -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.lifecycleScope import com.squareup.workflow1.ui.androidx.WorkflowAndroidXSupport.lifecycleOwnerFromViewTreeOrContextOrNull import kotlinx.coroutines.CoroutineName @@ -42,7 +42,7 @@ import kotlin.coroutines.EmptyCoroutineContext * later reattached_. The [block] _will not_ be re-started if the view is re-attached. * * The coroutine will be a child of the scope of the receiver's - * [LifecycleOwner][ViewTreeLifecycleOwner.get]. + * [LifecycleOwner][findViewTreeLifecycleOwner]. * * @param context The [CoroutineContext] in which to run the returned [CoroutineScope]. * This context _must not_ contain a [Job] – if it does, an [IllegalArgumentException] diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowAndroidXSupport.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowAndroidXSupport.kt index 08b2dd66b..bdf62f896 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowAndroidXSupport.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowAndroidXSupport.kt @@ -6,7 +6,7 @@ import android.view.View import androidx.activity.OnBackPressedDispatcherOwner import androidx.activity.findViewTreeOnBackPressedDispatcherOwner import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.findViewTreeSavedStateRegistryOwner import com.squareup.workflow1.ui.OnBackPressedDispatcherOwnerKey @@ -31,14 +31,14 @@ public object WorkflowAndroidXSupport { } /** - * Tries to get the parent lifecycle from the current view via [ViewTreeLifecycleOwner], if that + * Tries to get the parent lifecycle from the current view via [findViewTreeLifecycleOwner], if that * fails it looks up the context chain for a [LifecycleOwner], and if that fails it just returns - * null. This differs from [ViewTreeLifecycleOwner.get] because it will check the + * null. This differs from [findViewTreeLifecycleOwner] because it will check the * [View.getContext] if no owner is found in the view tree. */ @WorkflowUiExperimentalApi public fun lifecycleOwnerFromViewTreeOrContextOrNull(view: View): LifecycleOwner? = - ViewTreeLifecycleOwner.get(view) ?: view.context.ownerOrNull(LifecycleOwner::class) + view.findViewTreeLifecycleOwner() ?: view.context.ownerOrNull(LifecycleOwner::class) /** * Tries to get the parent [SavedStateRegistryOwner] from the current view via diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowLifecycleOwner.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowLifecycleOwner.kt index 640a0db25..c1c8f8d96 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowLifecycleOwner.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowLifecycleOwner.kt @@ -5,7 +5,7 @@ import android.view.View.OnAttachStateChangeListener import androidx.activity.OnBackPressedDispatcherOwner import androidx.activity.setViewTreeOnBackPressedDispatcherOwner import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.PRIVATE +import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle.Event import androidx.lifecycle.Lifecycle.State.DESTROYED @@ -14,8 +14,9 @@ import androidx.lifecycle.Lifecycle.State.RESUMED import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry -import androidx.lifecycle.LifecycleRegistry.createUnsafe -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.LifecycleRegistry.Companion.createUnsafe +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.setViewTreeLifecycleOwner import com.squareup.workflow1.ui.WorkflowUiExperimentalApi import com.squareup.workflow1.ui.androidx.WorkflowAndroidXSupport.lifecycleOwnerFromViewTreeOrContextOrNull import com.squareup.workflow1.ui.androidx.WorkflowLifecycleOwner.Companion.get @@ -23,10 +24,10 @@ import com.squareup.workflow1.ui.androidx.WorkflowLifecycleOwner.Companion.insta /** * An extension of [LifecycleOwner] that is always owned by a [View], is logically a child lifecycle - * of the next-nearest [ViewTreeLifecycleOwner] above it (it mirrors its parent's lifecycle until + * of the next-nearest [LifecycleOwner] above it (it mirrors its parent's lifecycle until * it's destroyed), and can be [asked to destroy][destroyOnDetach] itself early. * - * This type is meant to help integrate with [ViewTreeLifecycleOwner] by allowing the creation of a + * This type is meant to help integrate with [LifecycleOwner] by allowing the creation of a * tree of [LifecycleOwner]s that mirrors the view tree. * * Custom container views that use @@ -73,7 +74,7 @@ public interface WorkflowLifecycleOwner : LifecycleOwner { * * @param findParentLifecycle A function that is called whenever [view] is attached, and should * return the [Lifecycle] to use as the parent lifecycle. If not specified, defaults to looking - * up the view tree by calling [ViewTreeLifecycleOwner.get] on [view]'s parent, and if none is + * up the view tree by calling [findViewTreeLifecycleOwner] on [view]'s parent, and if none is * found, then looking up [view]'s context wrapper chain for something that implements * [LifecycleOwner]. This only needs to be passed if [view] will be used as the root of a new * view hierarchy, e.g. for a new dialog. If no parent lifecycle is found, then the lifecycle @@ -87,18 +88,18 @@ public interface WorkflowLifecycleOwner : LifecycleOwner { ) { RealWorkflowLifecycleOwner(findParentLifecycle).also { view.setViewTreeOnBackPressedDispatcherOwner(onBackPressedDispatcherOwner) - ViewTreeLifecycleOwner.set(view, it) + view.setViewTreeLifecycleOwner(it) view.addOnAttachStateChangeListener(it) } } /** - * Looks for the nearest [ViewTreeLifecycleOwner] on [view] and returns it if it's an instance + * Looks for the nearest [LifecycleOwner] on [view] and returns it if it's an instance * of [WorkflowLifecycleOwner]. Convenience function for retrieving the owner set by * [installOn]. */ public fun get(view: View): WorkflowLifecycleOwner? = - ViewTreeLifecycleOwner.get(view) as? WorkflowLifecycleOwner + view.findViewTreeLifecycleOwner() as? WorkflowLifecycleOwner private fun findParentViewTreeLifecycle(view: View): Lifecycle { // Start at our view's parent – if we look on our own view, we'll just get this back. @@ -128,6 +129,9 @@ internal class RealWorkflowLifecycleOwner( private val localLifecycle = if (enforceMainThread) LifecycleRegistry(this) else createUnsafe(this) + override val lifecycle: Lifecycle + get() = localLifecycle + /** * We can't rely on [localLifecycle] to know if we've actually attempted to destroy the lifecycle, * because there's a case where we can be about to destroy our lifecycle but we're still in the @@ -140,8 +144,8 @@ internal class RealWorkflowLifecycleOwner( private var hasBeenDestroyed = false /** - * The parent lifecycle found by calling [ViewTreeLifecycleOwner.get] on the owning view's parent - * (once it's attached), or if no [ViewTreeLifecycleOwner] is set, then by trying to find a + * The parent lifecycle found by calling [findViewTreeLifecycleOwner] on the owning view's parent + * (once it's attached), or if no [LifecycleOwner] is set, then by trying to find a * [LifecycleOwner] on the view's context. * * When the view is detached, we keep the reference to the previous parent @@ -193,8 +197,6 @@ internal class RealWorkflowLifecycleOwner( } } - override fun getLifecycle(): Lifecycle = localLifecycle - /** * @param isAttached Whether the view is [attached][View.isAttachedToWindow]. Must be passed * explicitly when called from the attach/detach callbacks, since the view property's value won't diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregator.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregator.kt index 788f5e2f3..1f4706e24 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregator.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregator.kt @@ -7,7 +7,7 @@ import androidx.lifecycle.Lifecycle.Event.ON_CREATE import androidx.lifecycle.Lifecycle.State.INITIALIZED import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.findViewTreeSavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner @@ -32,7 +32,7 @@ import com.squareup.workflow1.ui.WorkflowUiExperimentalApi * to each dialog's content view. * * Note that a [SavedStateRegistryOwner] works _in parallel_ to a - * [ViewTreeLifecycleOwner][androidx.lifecycle.ViewTreeLifecycleOwner]. + * [LifecycleOwner][androidx.lifecycle.LifecycleOwner]. * Use [WorkflowLifecycleOwner] to ensure one is properly installed. * * [attachToParentRegistry] must be called when the container view is attached to a window, @@ -188,7 +188,7 @@ public class WorkflowSavedStateRegistryAggregator { /** * Puts a new [SavedStateRegistryOwner] in place on [view], registered - * with its [ViewTreeLifecycleOwner]. (Use [WorkflowLifecycleOwner] to ensure + * with its [LifecycleOwner]. (Use [WorkflowLifecycleOwner] to ensure * one is properly installed.) * * **This method must be called before [view] is attached to a window.** @@ -224,7 +224,7 @@ public class WorkflowSavedStateRegistryAggregator { key: String, force: Boolean = false ) { - val lifecycleOwner = requireNotNull(ViewTreeLifecycleOwner.get(view)) { + val lifecycleOwner = requireNotNull(view.findViewTreeLifecycleOwner()) { "Expected $view($key) to have a ViewTreeLifecycleOwner. " + "Use WorkflowLifecycleOwner to fix that." } diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/DialogSession.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/DialogSession.kt index 558fccd23..f02b3b38a 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/DialogSession.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/DialogSession.kt @@ -164,8 +164,8 @@ internal class DialogSession( ?: holder.environment.map[OnBackPressedDispatcherOwnerKey] as? OnBackPressedDispatcherOwner ?: decorView.onBackPressedDispatcherOwnerOrNull() ?: object : OnBackPressedDispatcherOwner { - override fun getLifecycle(): Lifecycle = - error("To support back press handling extend ComponentDialog: $dialog") + override val lifecycle: Lifecycle + get() = error("To support back press handling extend ComponentDialog: $dialog") override fun getOnBackPressedDispatcher(): OnBackPressedDispatcher = error("To support back press handling extend ComponentDialog: $dialog") diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/LayeredDialogSessions.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/LayeredDialogSessions.kt index 208ec760e..8f0175062 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/LayeredDialogSessions.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/LayeredDialogSessions.kt @@ -12,7 +12,7 @@ import android.view.ViewTreeObserver.OnGlobalLayoutListener import androidx.core.view.doOnAttach import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import com.squareup.workflow1.ui.Compatible import com.squareup.workflow1.ui.ViewEnvironment import com.squareup.workflow1.ui.WorkflowUiExperimentalApi @@ -38,7 +38,7 @@ import java.util.UUID * - Makes [OverlayArea] available in the [ViewEnvironment], * and uses it to drive calls to [OverlayDialogHolder.onUpdateBounds]. * - * - Provides a [ViewTreeLifecycleOwner] per managed Dialog, and view persistence support, + * - Provides a [LifecycleOwner] per managed Dialog, and view persistence support, * both for classic [View.onSaveInstanceState] and * Jetpack [SavedStateRegistry][androidx.savedstate.SavedStateRegistry]. * @@ -59,7 +59,7 @@ import java.util.UUID * * When a new [DialogSession] begins: * - * - a [ViewTreeLifecycleOwner] is created as a child to the one provided + * - a [LifecycleOwner] is created as a child to the one provided * by [getParentLifecycleOwner] * * - An appropriately scoped [SavedStateRegistry][androidx.savedstate.SavedStateRegistry] @@ -78,7 +78,7 @@ import java.util.UUID * * When [update] is called without a matching [Overlay], or the * [parent Lifecycle][getParentLifecycleOwner] ends, the [DialogSession] ends, - * its [ViewTreeLifecycleOwner] is destroyed, and the Dialog is + * its [LifecycleOwner] is destroyed, and the Dialog is * [dismissed][android.app.Dialog.dismiss]. * * @param bounds made available to managed dialogs via the [OverlayArea] @@ -156,7 +156,7 @@ public class LayeredDialogSessions private constructor( * * Each dialog has its own [WorkflowLifecycleOwner], which starts when the dialog * is shown, and is destroyed when it is dismissed. Views nested in a managed dialog - * can use [ViewTreeLifecycleOwner][androidx.lifecycle.ViewTreeLifecycleOwner] as + * can use [LifecycleOwner][androidx.lifecycle.LifecycleOwner] as * usual. * * @param updateBody function to be called before updating the dialogs, presumably @@ -350,7 +350,7 @@ public class LayeredDialogSessions private constructor( view.cancelPendingInputEvents() } ) { - checkNotNull(ViewTreeLifecycleOwner.get(view)) { + checkNotNull(view.findViewTreeLifecycleOwner()) { "Expected a ViewTreeLifecycleOwner on $view" } }.also { dialogs -> diff --git a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/ViewStateCache.kt b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/ViewStateCache.kt index aee98e7ec..0e126c693 100644 --- a/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/ViewStateCache.kt +++ b/workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/container/ViewStateCache.kt @@ -8,7 +8,7 @@ import android.os.Parcelable.Creator import android.util.SparseArray import android.view.View import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.PRIVATE +import androidx.annotation.VisibleForTesting.Companion.PRIVATE import androidx.savedstate.SavedStateRegistryOwner import com.squareup.workflow1.ui.Compatible.Companion.keyFor import com.squareup.workflow1.ui.NamedScreen diff --git a/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/ViewLaunchWhenAttachedTest.kt b/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/ViewLaunchWhenAttachedTest.kt index 3aace24c7..55a36ce9c 100644 --- a/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/ViewLaunchWhenAttachedTest.kt +++ b/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/ViewLaunchWhenAttachedTest.kt @@ -4,7 +4,8 @@ import android.content.res.Resources.NotFoundException import android.view.View import android.view.View.OnAttachStateChangeListener import androidx.lifecycle.Lifecycle.Event.ON_DESTROY -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.setViewTreeLifecycleOwner import androidx.lifecycle.testing.TestLifecycleOwner import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineName @@ -156,7 +157,7 @@ internal class ViewLaunchWhenAttachedTest { assertThat(innerJob!!.isActive).isTrue() // Action: cancel parent scope! - (ViewTreeLifecycleOwner.get(view) as TestLifecycleOwner) + (view.findViewTreeLifecycleOwner() as TestLifecycleOwner) .handleLifecycleEvent(ON_DESTROY) assertThat(innerJob!!.isCancelled).isTrue() @@ -222,8 +223,7 @@ internal class ViewLaunchWhenAttachedTest { return mock(defaultAnswer = RETURNS_DEEP_STUBS).also { mockTags(it) mockAttachedToWindow(it) - ViewTreeLifecycleOwner.set( - it, + it.setViewTreeLifecycleOwner( TestLifecycleOwner(coroutineDispatcher = UnconfinedTestDispatcher()) ) } diff --git a/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/RealWorkflowLifecycleOwnerTest.kt b/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/RealWorkflowLifecycleOwnerTest.kt index 84d2c4c87..2b6cc273a 100644 --- a/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/RealWorkflowLifecycleOwnerTest.kt +++ b/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/RealWorkflowLifecycleOwnerTest.kt @@ -2,7 +2,6 @@ package com.squareup.workflow1.ui.androidx import android.content.Context import android.view.View -import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle.Event import androidx.lifecycle.Lifecycle.State.CREATED import androidx.lifecycle.Lifecycle.State.DESTROYED @@ -203,8 +202,7 @@ internal class RealWorkflowLifecycleOwnerTest { private fun ensureParentLifecycle(): LifecycleRegistry { if (parentLifecycle == null) { val owner = object : LifecycleOwner { - val lifecycle = LifecycleRegistry.createUnsafe(this) - override fun getLifecycle(): Lifecycle = lifecycle + override val lifecycle = LifecycleRegistry.createUnsafe(this) } parentLifecycle = owner.lifecycle } diff --git a/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregatorTest.kt b/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregatorTest.kt index 816a1de3f..9939c59db 100644 --- a/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregatorTest.kt +++ b/workflow-ui/core-android/src/test/java/com/squareup/workflow1/ui/androidx/WorkflowSavedStateRegistryAggregatorTest.kt @@ -25,7 +25,8 @@ import kotlin.test.assertFailsWith @OptIn(WorkflowUiExperimentalApi::class) internal class WorkflowSavedStateRegistryAggregatorTest { private val fakeOnBack = object : OnBackPressedDispatcherOwner { - override fun getLifecycle(): Lifecycle = error("") + override val lifecycle: Lifecycle + get() = error("") override fun getOnBackPressedDispatcher(): OnBackPressedDispatcher = error("") } @@ -351,7 +352,8 @@ internal class WorkflowSavedStateRegistryAggregatorTest { override val savedStateRegistry: SavedStateRegistry get() = stateRegistryController.savedStateRegistry - override fun getLifecycle(): Lifecycle = lifecycleRegistry + override val lifecycle: Lifecycle + get() = lifecycleRegistry fun saveToBundle(): Bundle = Bundle().also { bundle -> stateRegistryController.performSave(bundle) diff --git a/workflow-ui/internal-testing-android/src/main/java/com/squareup/workflow1/ui/internal/test/AbstractLifecycleTestActivity.kt b/workflow-ui/internal-testing-android/src/main/java/com/squareup/workflow1/ui/internal/test/AbstractLifecycleTestActivity.kt index d98aba8c3..8cdde40ab 100644 --- a/workflow-ui/internal-testing-android/src/main/java/com/squareup/workflow1/ui/internal/test/AbstractLifecycleTestActivity.kt +++ b/workflow-ui/internal-testing-android/src/main/java/com/squareup/workflow1/ui/internal/test/AbstractLifecycleTestActivity.kt @@ -9,7 +9,7 @@ import android.widget.FrameLayout import androidx.lifecycle.Lifecycle.Event import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.ViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeLifecycleOwner import com.squareup.workflow1.ui.Screen import com.squareup.workflow1.ui.ScreenViewFactory import com.squareup.workflow1.ui.ScreenViewHolder @@ -200,8 +200,8 @@ public abstract class AbstractLifecycleTestActivity : WorkflowUiTestActivity() { super.onAttachedToWindow() viewObserver?.onAttachedToWindow(this, rendering) - ViewTreeLifecycleOwner.get(this)!!.lifecycle.removeObserver(lifecycleObserver) - ViewTreeLifecycleOwner.get(this)!!.lifecycle.addObserver(lifecycleObserver) + this.findViewTreeLifecycleOwner()!!.lifecycle.removeObserver(lifecycleObserver) + this.findViewTreeLifecycleOwner()!!.lifecycle.addObserver(lifecycleObserver) } override fun onDetachedFromWindow() { diff --git a/workflow-ui/radiography/dependencies/releaseRuntimeClasspath.txt b/workflow-ui/radiography/dependencies/releaseRuntimeClasspath.txt index b3bd6821b..6d8c54564 100644 --- a/workflow-ui/radiography/dependencies/releaseRuntimeClasspath.txt +++ b/workflow-ui/radiography/dependencies/releaseRuntimeClasspath.txt @@ -1,19 +1,23 @@ androidx.activity:activity:1.6.1 -androidx.annotation:annotation-experimental:1.1.0 -androidx.annotation:annotation:1.2.0 -androidx.arch.core:core-common:2.1.0 -androidx.arch.core:core-runtime:2.1.0 +androidx.annotation:annotation-experimental:1.3.0 +androidx.annotation:annotation-jvm:1.6.0 +androidx.annotation:annotation:1.6.0 +androidx.arch.core:core-common:2.2.0 +androidx.arch.core:core-runtime:2.2.0 androidx.collection:collection:1.1.0 -androidx.concurrent:concurrent-futures:1.0.0 -androidx.core:core-ktx:1.6.0 -androidx.core:core:1.8.0 -androidx.lifecycle:lifecycle-common:2.5.1 -androidx.lifecycle:lifecycle-livedata-core:2.5.1 -androidx.lifecycle:lifecycle-runtime-ktx:2.5.1 -androidx.lifecycle:lifecycle-runtime:2.5.1 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.1 -androidx.lifecycle:lifecycle-viewmodel:2.5.1 +androidx.concurrent:concurrent-futures:1.1.0 +androidx.core:core-ktx:1.10.0 +androidx.core:core:1.10.0 +androidx.interpolator:interpolator:1.0.0 +androidx.lifecycle:lifecycle-common:2.6.1 +androidx.lifecycle:lifecycle-livedata-core:2.6.1 +androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 +androidx.lifecycle:lifecycle-runtime:2.6.1 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 +androidx.lifecycle:lifecycle-viewmodel:2.6.1 +androidx.profileinstaller:profileinstaller:1.3.0 androidx.savedstate:savedstate:1.2.1 +androidx.startup:startup-runtime:1.1.1 androidx.tracing:tracing:1.0.0 androidx.transition:transition:1.4.1 androidx.versionedparcelable:versionedparcelable:1.1.1