From 4702f6951534445c711e77774426632d4ed3bc8d Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy Date: Wed, 4 Dec 2024 14:09:40 +0100 Subject: [PATCH] Fix the upnp service discover crashing when browsing while the remote access is running --- .../videolan/vlc/providers/BrowserProvider.kt | 12 ++++- .../videolan/vlc/providers/NetworkProvider.kt | 44 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/application/vlc-android/src/org/videolan/vlc/providers/BrowserProvider.kt b/application/vlc-android/src/org/videolan/vlc/providers/BrowserProvider.kt index bd7418cb4..5e5087660 100644 --- a/application/vlc-android/src/org/videolan/vlc/providers/BrowserProvider.kt +++ b/application/vlc-android/src/org/videolan/vlc/providers/BrowserProvider.kt @@ -130,7 +130,7 @@ abstract class BrowserProvider(val context: Context, val dataset: LiveDataset action.deferred.complete(browseUrlImpl(action.url)) } } } + /** + * Clean the media browser + * + */ + open fun cleanMediaBrowser() { + mediabrowser = null + } + protected open fun initBrowser() { if (mediabrowser == null) { registerCreator { MediaBrowser(VLCInstance.getInstance(context), null, browserHandler) } diff --git a/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt b/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt index 5dc5a73d1..956253540 100644 --- a/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt +++ b/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt @@ -24,18 +24,54 @@ import android.content.Context import androidx.core.net.toUri import androidx.lifecycle.Observer import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.videolan.libvlc.util.MediaBrowser import org.videolan.medialibrary.interfaces.Medialibrary import org.videolan.medialibrary.interfaces.media.MediaWrapper import org.videolan.medialibrary.media.DummyItem import org.videolan.medialibrary.media.MediaLibraryItem +import org.videolan.tools.AppScope import org.videolan.tools.NetworkMonitor import org.videolan.tools.livedata.LiveDataset import org.videolan.vlc.R +import java.util.concurrent.atomic.AtomicBoolean class NetworkProvider(context: Context, dataset: LiveDataset, url: String? = null): BrowserProvider(context, dataset, url, Medialibrary.SORT_FILENAME, false), Observer> { + override fun initBrowser() { + if (alreadyRunning.getAndSet(true)) { + // Use the cached [MediaBrowser] instead of creating a new one + if (cachedMediaBrowser != null) { + mediabrowser = cachedMediaBrowser + } else { + AppScope.launch(Dispatchers.IO) { + while (cachedMediaBrowser == null && alreadyRunning.get()) { + delay(50) + } + if (alreadyRunning.get()) { + mediabrowser = cachedMediaBrowser + } else { + super.initBrowser() + } + } + } + return + } + super.initBrowser() + cachedMediaBrowser = mediabrowser + } + + /** + * Also clean the cached [MediaBrowser] + * + */ + override fun cleanMediaBrowser() { + super.cleanMediaBrowser() + cachedMediaBrowser = null + alreadyRunning.set(false) + } override suspend fun browseRootImpl() { dataset.clear() @@ -101,4 +137,12 @@ class NetworkProvider(context: Context, dataset: LiveDataset, } return null } + + companion object { + // For network discovery, we don't want multiple [MediaBrowser] simultaneously running + // as it will spawn two service discovery that VLC cannot run simultaneously + // So we cache the [MediaBrowser] instance here and clean it when the [NetworkProvider] is cleared + var cachedMediaBrowser: MediaBrowser? = null + var alreadyRunning = AtomicBoolean(false) + } } \ No newline at end of file