[Android] Set connection as Flow
Geoffrey Métais
git at videolan.org
Fri Feb 21 14:34:08 CET 2020
vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Tue Feb 18 11:23:46 2020 +0100| [719ef5f381470375c10f914882e4e37cd9fac472] | committer: Geoffrey Métais
Set connection as Flow
> https://code.videolan.org/videolan/vlc-android/commit/719ef5f381470375c10f914882e4e37cd9fac472
---
.../main/java/org/videolan/tools/NetworkMonitor.kt | 44 ++++++++++------------
.../src/org/videolan/vlc/RendererDelegate.kt | 4 +-
.../vlc/repository/BrowserFavRepository.kt | 15 +++++---
3 files changed, 31 insertions(+), 32 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 bc176dd4e..532b80638 100644
--- a/application/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
+++ b/application/tools/src/main/java/org/videolan/tools/NetworkMonitor.kt
@@ -10,29 +10,25 @@ import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import androidx.lifecycle.*
-import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.channels.ConflatedBroadcastChannel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.consumeAsFlow
import java.lang.ref.WeakReference
import java.net.NetworkInterface
import java.net.SocketException
-interface NetworkObserver {
- fun onNetworkChanged()
-}
-
class NetworkMonitor(private val context: Context) : LifecycleObserver {
private var registered = false
private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
- val connected = MutableLiveData<Boolean>()
- @Volatile
- var isMobile = true
- private set
- @Volatile
- var isVPN = false
- private set
- private var networkObservers: MutableList<WeakReference<NetworkObserver>> = mutableListOf()
+ val connection = ConflatedBroadcastChannel(Connection(connected = false, mobile = true, vpn = false))
+ val connectionFlow : Flow<Connection>
+ get() = connection.openSubscription().consumeAsFlow()
+ val connected : Boolean
+ get() = connection.value.connected
+ val isLan : Boolean
+ get() = connection.value.run { connected && !mobile }
+ val lanAllowed : Boolean
+ get() = connection.value.run { connected && (!mobile || vpn) }
init {
ProcessLifecycleOwner.get().lifecycle.addObserver(this at NetworkMonitor)
@@ -82,18 +78,16 @@ class NetworkMonitor(private val context: Context) : LifecycleObserver {
ConnectivityManager.CONNECTIVITY_ACTION -> {
val networkInfo = cm.activeNetworkInfo
val isConnected = networkInfo != null && networkInfo.isConnected
- isMobile = isConnected && networkInfo!!.type == ConnectivityManager.TYPE_MOBILE
- isVPN = isConnected && updateVPNStatus()
- if (connected.value == null || isConnected != connected.value) {
- connected.value = isConnected
- }
- networkObservers.forEach { it.get()?.onNetworkChanged() }
+ 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)
}
}
}
-
}
-
- companion object : SingletonHolder<NetworkMonitor, Context>({ NetworkMonitor(it) })
+ companion object : SingletonHolder<NetworkMonitor, Context>({ NetworkMonitor(it.applicationContext) })
}
+
+class Connection(val connected: Boolean, val mobile: Boolean, val vpn: Boolean)
diff --git a/application/vlc-android/src/org/videolan/vlc/RendererDelegate.kt b/application/vlc-android/src/org/videolan/vlc/RendererDelegate.kt
index 06b08974d..491f0fb7a 100644
--- a/application/vlc-android/src/org/videolan/vlc/RendererDelegate.kt
+++ b/application/vlc-android/src/org/videolan/vlc/RendererDelegate.kt
@@ -20,6 +20,8 @@
package org.videolan.vlc
import kotlinx.coroutines.*
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
import org.videolan.libvlc.RendererDiscoverer
import org.videolan.libvlc.RendererItem
import org.videolan.resources.AppContextProvider
@@ -42,7 +44,7 @@ object RendererDelegate : RendererDiscoverer.EventListener {
@Volatile private var started = false
init {
- NetworkMonitor.getInstance(AppContextProvider.appContext).connected.observeForever { AppScope.launch { if (it == true) start() else stop() } }
+ NetworkMonitor.getInstance(AppContextProvider.appContext).connectionFlow.onEach { if (it.connected) start() else stop() }.launchIn(AppScope)
}
suspend fun start() {
diff --git a/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt b/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt
index 0913bcd7e..976e71df8 100644
--- a/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt
+++ b/application/vlc-android/src/org/videolan/vlc/repository/BrowserFavRepository.kt
@@ -24,12 +24,15 @@ import android.content.Context
import android.net.Uri
import androidx.annotation.WorkerThread
import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.asLiveData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.videolan.medialibrary.interfaces.media.MediaWrapper
+import org.videolan.resources.AppContextProvider
import org.videolan.resources.TYPE_LOCAL_FAV
import org.videolan.resources.TYPE_NETWORK_FAV
import org.videolan.tools.IOScopedObject
+import org.videolan.tools.NetworkMonitor
import org.videolan.tools.SingletonHolder
import org.videolan.vlc.ExternalMonitor
import org.videolan.vlc.database.BrowserFavDao
@@ -41,6 +44,8 @@ import java.util.*
class BrowserFavRepository(private val browserFavDao: BrowserFavDao) : IOScopedObject() {
+ private val networkMonitor = NetworkMonitor.getInstance(AppContextProvider.appContext)
+
private val networkFavs by lazy { browserFavDao.getAllNetwrokFavs() }
val browserFavorites by lazy { browserFavDao.getAll() }
@@ -58,11 +63,9 @@ class BrowserFavRepository(private val browserFavDao: BrowserFavDao) : IOScopedO
val networkFavorites by lazy {
MediatorLiveData<List<MediaWrapper>>().apply {
addSource(networkFavs) { value = convertFavorites(it).filterNetworkFavs() }
- addSource(ExternalMonitor.connected) {
- launch(Dispatchers.Main.immediate) {
- val favList = convertFavorites(networkFavs.value)
- if (favList.isNotEmpty()) value = if (it == true) favList.filterNetworkFavs() else emptyList()
- }
+ addSource(networkMonitor.connectionFlow.asLiveData()) {
+ val favList = convertFavorites(networkFavs.value)
+ if (favList.isNotEmpty()) value = if (it.connected) favList.filterNetworkFavs() else emptyList()
}
}
}
@@ -75,7 +78,7 @@ class BrowserFavRepository(private val browserFavDao: BrowserFavDao) : IOScopedO
private fun List<MediaWrapper>.filterNetworkFavs() : List<MediaWrapper> {
return when {
isEmpty() -> this
- !ExternalMonitor.isConnected -> emptyList()
+ !networkMonitor.connected -> emptyList()
!ExternalMonitor.allowLan() -> {
val schemes = Arrays.asList("ftp", "sftp", "ftps", "http", "https")
mutableListOf<MediaWrapper>().apply { this at filterNetworkFavs.filterTo(this) { schemes.contains(it.uri.scheme) } }
More information about the Android
mailing list