[Android] Replace ConflatedBroadcastChannels by StateFlows

Geoffrey Métais git at videolan.org
Mon May 11 14:02:51 CEST 2020


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Mon May 11 11:43:22 2020 +0200| [4b6d909d03ac40d4b82505ad5a25cd07cfbd148e] | committer: Geoffrey Métais

Replace ConflatedBroadcastChannels by StateFlows

> https://code.videolan.org/videolan/vlc-android/commit/4b6d909d03ac40d4b82505ad5a25cd07cfbd148e
---

 .../src/main/java/org/videolan/tools/NetworkMonitor.kt  | 17 ++++++-----------
 .../vlc-android/src/org/videolan/vlc/ExternalMonitor.kt |  2 +-
 .../vlc-android/src/org/videolan/vlc/PlaybackService.kt | 14 +++++---------
 .../org/videolan/vlc/gui/browser/FileBrowserFragment.kt |  3 +--
 .../src/org/videolan/vlc/gui/helpers/hf/OtgAccess.kt    |  9 ++++-----
 5 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/application/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt b/application/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
index 9d9071102..0cc53c1a7 100644
--- a/application/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
+++ b/application/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
@@ -13,24 +13,20 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.OnLifecycleEvent
 import androidx.lifecycle.ProcessLifecycleOwner
-import kotlinx.coroutines.channels.ConflatedBroadcastChannel
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.asFlow
+import kotlinx.coroutines.flow.MutableStateFlow
 import java.net.NetworkInterface
 import java.net.SocketException
 
 class NetworkMonitor(private val context: Context) : LifecycleObserver {
     private var registered = false
     private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
-    val connection = ConflatedBroadcastChannel(Connection(connected = false, mobile = true, vpn = false))
-    val connectionFlow : Flow<Connection>
-        get() = connection.asFlow()
+    val connectionFlow = MutableStateFlow(Connection(connected = false, mobile = true, vpn = false))
     val connected : Boolean
-        get() = connection.value.connected
+        get() = connectionFlow.value.connected
     val isLan : Boolean
-        get() = connection.value.run { connected && !mobile }
+        get() = connectionFlow.value.run { connected && !mobile }
     val lanAllowed : Boolean
-        get() = connection.value.run { connected && (!mobile || vpn) }
+        get() = connectionFlow.value.run { connected && (!mobile || vpn) }
     val receiver = object : BroadcastReceiver() {
         @SuppressLint("MissingPermission")
         override fun onReceive(context: Context?, intent: Intent?) {
@@ -40,8 +36,7 @@ class NetworkMonitor(private val context: Context) : LifecycleObserver {
                     val isConnected = networkInfo != null && networkInfo.isConnected
                     val isMobile = isConnected && networkInfo!!.type == ConnectivityManager.TYPE_MOBILE
                     val isVPN = isConnected && updateVPNStatus()
-                    val conn = Connection(isConnected, isMobile, isVPN)
-                    if (connection.value != conn) connection.offer(conn)
+                    connectionFlow.value = Connection(isConnected, isMobile, isVPN)
                 }
 
             }
diff --git a/application/vlc-android/src/org/videolan/vlc/ExternalMonitor.kt b/application/vlc-android/src/org/videolan/vlc/ExternalMonitor.kt
index 2eaf942cb..96a395c21 100644
--- a/application/vlc-android/src/org/videolan/vlc/ExternalMonitor.kt
+++ b/application/vlc-android/src/org/videolan/vlc/ExternalMonitor.kt
@@ -105,7 +105,7 @@ object ExternalMonitor : BroadcastReceiver(), LifecycleObserver, CoroutineScope
                 }
             }
             UsbManager.ACTION_USB_DEVICE_DETACHED -> if (intent.hasExtra(UsbManager.EXTRA_DEVICE)) {
-                OtgAccess.otgRoot.offer(null)
+                OtgAccess.otgRoot.value = null
                 val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                 devices.remove(device)
             }
diff --git a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
index a6787741e..ac92a43b4 100644
--- a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
@@ -52,11 +52,9 @@ import androidx.media.MediaBrowserServiceCompat
 import androidx.media.session.MediaButtonReceiver
 import kotlinx.coroutines.*
 import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.ConflatedBroadcastChannel
 import kotlinx.coroutines.channels.SendChannel
 import kotlinx.coroutines.channels.actor
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.asFlow
+import kotlinx.coroutines.flow.MutableStateFlow
 import org.videolan.libvlc.MediaPlayer
 import org.videolan.libvlc.RendererItem
 import org.videolan.libvlc.interfaces.IMedia
@@ -496,7 +494,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
         restartPlayer.observe(this, Observer { restartMediaPlayer() })
         headSetDetection.observe(this, Observer { detectHeadset(it) })
         equalizer.observe(this, Observer { setEqualizer(it) })
-        instanceChannel.safeOffer(this)
+        serviceFlow.value = this
     }
 
     private fun setupScope() {
@@ -564,7 +562,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
     }
 
     override fun onDestroy() {
-        instanceChannel.safeOffer(null)
+        serviceFlow.value = null
         dispatcher.onServicePreSuperOnDestroy()
         super.onDestroy()
         handler.removeCallbacksAndMessages(null)
@@ -1316,11 +1314,9 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
     }
 
     companion object {
-        private val instanceChannel = ConflatedBroadcastChannel<PlaybackService?>(null)
+        val serviceFlow = MutableStateFlow<PlaybackService?>(null)
         val instance : PlaybackService?
-            get() = instanceChannel.valueOrNull
-        val serviceFlow : Flow<PlaybackService?>
-            get() = instanceChannel.asFlow()
+            get() = serviceFlow.value
 
         val renderer = RendererLiveData()
         val restartPlayer = LiveEvent<Boolean>()
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.kt
index 725e251e1..400a43f4d 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.kt
@@ -118,8 +118,7 @@ open class FileBrowserFragment : BaseBrowserFragment() {
                     browseOtgDevice(rootUri, title)
                 } else {
                     lifecycleScope.launchWhenStarted {
-                        val otgRoot = OtgAccess.otgRoot.asFlow()
-                        val uri = otgRoot.filterNotNull().first()
+                        val uri = OtgAccess.otgRoot.filterNotNull().first()
                         browseOtgDevice(uri, title)
                     }
                     requireActivity().requestOtgRoot()
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/hf/OtgAccess.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/hf/OtgAccess.kt
index 6d352d623..95e691f1b 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/hf/OtgAccess.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/hf/OtgAccess.kt
@@ -31,10 +31,9 @@ import android.util.Log
 import androidx.annotation.WorkerThread
 import androidx.documentfile.provider.DocumentFile
 import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.channels.ConflatedBroadcastChannel
+import kotlinx.coroutines.flow.MutableStateFlow
 import org.videolan.medialibrary.MLServiceLocator
 import org.videolan.medialibrary.interfaces.media.MediaWrapper
-import org.videolan.tools.safeOffer
 
 const val SAF_REQUEST = 85
 const val TAG = "OtgAccess"
@@ -58,13 +57,13 @@ class OtgAccess : BaseHeadlessFragment() {
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
-        if (intent != null && requestCode == SAF_REQUEST) otgRoot.safeOffer(intent.data)
+        if (intent != null && requestCode == SAF_REQUEST) otgRoot.value = intent.data
         else super.onActivityResult(requestCode, resultCode, intent)
         exit()
     }
 
     companion object {
-        val otgRoot = ConflatedBroadcastChannel<Uri?>(null)
+        val otgRoot = MutableStateFlow<Uri?>(null)
     }
 }
 
@@ -74,7 +73,7 @@ fun FragmentActivity.requestOtgRoot() {
 
 @WorkerThread
 fun getDocumentFiles(context: Context, path: String) : List<MediaWrapper>? {
-    val rootUri = OtgAccess.otgRoot.valueOrNull ?: return null
+    val rootUri = OtgAccess.otgRoot.value ?: return null
 //    else Uri.Builder().scheme("content")
 //            .authority(OTG_CONTENT_AUTHORITY)
 //            .path(path.substringBefore(':'))



More information about the Android mailing list