Commit 719ef5f3 authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

Set connection as Flow

parent b8f29651
......@@ -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@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)
......@@ -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() {
......
......@@ -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@filterNetworkFavs.filterTo(this) { schemes.contains(it.uri.scheme) } }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment