[Android] Fix the upnp service discover crashing when browsing while the remote access is running
Nicolas Pomepuy
git at videolan.org
Fri Dec 6 11:11:58 UTC 2024
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Dec 4 14:09:40 2024 +0100| [4702f6951534445c711e77774426632d4ed3bc8d] | committer: Duncan McNamara
Fix the upnp service discover crashing when browsing while the remote access is running
> https://code.videolan.org/videolan/vlc-android/commit/4702f6951534445c711e77774426632d4ed3bc8d
---
.../org/videolan/vlc/providers/BrowserProvider.kt | 12 +++++-
.../org/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 bd7418cb44..5e5087660b 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<Me
mediabrowser?.release()
} catch (e: IllegalStateException) {
}
- mediabrowser = null
+ cleanMediaBrowser()
}
}
}
@@ -152,13 +152,21 @@ abstract class BrowserProvider(val context: Context, val dataset: LiveDataset<Me
mediabrowser?.release()
} catch (e: Exception) {
}
- mediabrowser = null
+ cleanMediaBrowser()
}
is BrowseUrl -> 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 5dc5a73d1f..9562535403 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<MediaLibraryItem>, url: String? = null): BrowserProvider(context, dataset, url, Medialibrary.SORT_FILENAME, false), Observer<List<MediaWrapper>> {
+ 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<MediaLibraryItem>,
}
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
More information about the Android
mailing list