Merge "Have FlowLiveData.asFlow use callbackFlow" into androidx-main
diff --git a/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt b/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt
index 7c2d8ed..fd50175 100644
--- a/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt
+++ b/lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/FlowLiveData.kt
@@ -27,10 +27,11 @@
 import kotlinx.coroutines.DelicateCoroutinesApi
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.conflate
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
@@ -102,24 +103,20 @@
  * LiveData due to a slow collector, so collector always gets the most recent value emitted.
  */
 @OptIn(DelicateCoroutinesApi::class)
-public fun <T> LiveData<T>.asFlow(): Flow<T> = flow {
-    val channel = Channel<T>(Channel.CONFLATED)
+public fun <T> LiveData<T>.asFlow(): Flow<T> = callbackFlow {
     val observer = Observer<T> {
-        channel.trySend(it)
+        trySend(it)
     }
     withContext(Dispatchers.Main.immediate) {
         observeForever(observer)
     }
-    try {
-        for (value in channel) {
-            emit(value)
-        }
-    } finally {
+
+    awaitClose {
         GlobalScope.launch(Dispatchers.Main.immediate) {
             removeObserver(observer)
         }
     }
-}
+}.conflate()
 
 /**
  * Creates a LiveData that has values collected from the origin [Flow].
diff --git a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt
index 97cdd15..ab075f6 100644
--- a/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt
+++ b/lifecycle/lifecycle-livedata-ktx/src/test/java/androidx/lifecycle/LiveDataAsFlowTest.kt
@@ -86,11 +86,14 @@
     fun reusingFlow() {
         val ld = MutableLiveData<Int>()
         val flow = ld.asFlow()
-        mainScope.launch { ld.value = 1 }
         val firstCollection = testScope.launch {
             assertThat(flow.first()).isEqualTo(1)
         }
         scopes.triggerAllActions()
+        assertThat(ld.hasActiveObservers()).isTrue()
+
+        mainScope.launch { ld.value = 1 }
+        scopes.triggerAllActions()
         // check that we're done with previous collection
         assertThat(ld.hasActiveObservers()).isFalse()
         assertThat(firstCollection.isCompleted).isTrue()
@@ -119,7 +122,7 @@
             assertThat(flowB.take(2).toList()).isEqualTo(listOf(1, 2))
         }
         scopes.triggerAllActions()
-        assertThat(ld.hasActiveObservers())
+        assertThat(ld.hasActiveObservers()).isTrue()
 
         mainScope.launch { ld.value = 1 }
         scopes.triggerAllActions()