[Android] Add an endpoint to receive the resume confirmation from the remote access client
Nicolas Pomepuy
git at videolan.org
Mon Nov 18 13:23:22 UTC 2024
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Fri Nov 15 13:16:21 2024 +0100| [45eba604317f20a21676c7407580d6d4ac6dde5e] | committer: Duncan McNamara
Add an endpoint to receive the resume confirmation from the remote access client
> https://code.videolan.org/videolan/vlc-android/commit/45eba604317f20a21676c7407580d6d4ac6dde5e
---
.../vlc/gui/AudioPlayerContainerActivity.kt | 9 +++-
.../videolan/vlc/gui/video/VideoPlayerActivity.kt | 8 +++-
.../videolan/vlc/webserver/RemoteAccessRouting.kt | 50 +++++++++++++++++++++-
3 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt
index b483824d5d..d1fbf7dcb3 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/AudioPlayerContainerActivity.kt
@@ -112,6 +112,8 @@ open class AudioPlayerContainerActivity : BaseActivity(), KeycodeListener, Sched
val playlistTipsDelegate: AudioPlaylistTipsDelegate by lazy(LazyThreadSafetyMode.NONE) { AudioPlaylistTipsDelegate(this) }
private val playerKeyListenerDelegate: PlayerKeyListenerDelegate by lazy(LazyThreadSafetyMode.NONE) { PlayerKeyListenerDelegate(this at AudioPlayerContainerActivity) }
val shownTips = ArrayList<Int>()
+ private var currentConfirmationDialog: AlertDialog? = null
+
protected val currentFragment: Fragment?
get() = supportFragmentManager.findFragmentById(R.id.fragment_placeholder)
@@ -119,7 +121,7 @@ open class AudioPlayerContainerActivity : BaseActivity(), KeycodeListener, Sched
get() = toolbar.menu
private var observer: Observer<in WaitConfirmation?> = Observer {
- it?.let {
+ if (it != null) {
// Every AudioPlayerContainerActivity instance will receive this. To avoid having the
// Dialog pop every time the user goes to previous instances, stop the
// showConfirmationResumeDialog once it's been shown.
@@ -127,7 +129,8 @@ open class AudioPlayerContainerActivity : BaseActivity(), KeycodeListener, Sched
it.used = true
showConfirmResumeDialog(it)
}
- }
+ } else
+ currentConfirmationDialog?.dismiss()
}
open fun isTransparent(): Boolean = false
@@ -276,6 +279,7 @@ open class AudioPlayerContainerActivity : BaseActivity(), KeycodeListener, Sched
lifecycleScope.launch { PlaybackService.instance?.playlistManager?.playIndex(confirmation.index, confirmation.flags, forceRestart = true) }
}
.setOnDismissListener {
+ currentConfirmationDialog = null
PlaybackService.waitConfirmation.postValue(null)
}
.create().apply {
@@ -290,6 +294,7 @@ open class AudioPlayerContainerActivity : BaseActivity(), KeycodeListener, Sched
true
} else false
}
+ currentConfirmationDialog = this
show()
}
}
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
index 18644c4301..3bb1c4d044 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt
@@ -267,6 +267,7 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
private var savedTime: Long = -1
lateinit var windowLayoutInfo: WindowLayoutInfo
+ private var currentConfirmationDialog: AlertDialog? = null
/**
* For uninterrupted switching between audio and video mode
@@ -2346,6 +2347,7 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
lifecycleScope.launch { service?.playlistManager?.playIndex(confirmation.index, confirmation.flags, forceRestart = true) }
}
.setOnDismissListener {
+ currentConfirmationDialog = null
PlaybackService.waitConfirmation.postValue(null)
}
.create().apply {
@@ -2357,6 +2359,7 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
true
} else false
}
+ currentConfirmationDialog = this
show()
}
}
@@ -2479,7 +2482,10 @@ open class VideoPlayerActivity : AppCompatActivity(), PlaybackService.Callback,
}
service.addCallback(this)
service.playlistManager.waitForConfirmation.observe(this) {
- if (it != null) showConfirmResumeDialog(it)
+ if (it != null)
+ showConfirmResumeDialog(it)
+ else
+ currentConfirmationDialog?.dismiss()
}
//if (isTalkbackIsEnabled()) overlayDelegate.showOverlayTimeout(OVERLAY_INFINITE)
} else if (this.service != null) {
diff --git a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
index 2fb707128e..a87becc3b0 100644
--- a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
+++ b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
@@ -26,8 +26,6 @@ package org.videolan.vlc.webserver
import android.content.Context
import android.content.res.Resources
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.text.format.Formatter
@@ -108,6 +106,7 @@ import org.videolan.vlc.gui.helpers.getColoredBitmapFromColor
import org.videolan.vlc.gui.preferences.search.PreferenceParser
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.media.PlaylistManager
+import org.videolan.vlc.media.ResumeStatus
import org.videolan.vlc.providers.BrowserProvider
import org.videolan.vlc.providers.FileBrowserProvider
import org.videolan.vlc.providers.StorageProvider
@@ -982,6 +981,53 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) {
}
call.respond(HttpStatusCode.NotFound)
}
+ get("/resume") {
+ val resume = (call.request.queryParameters["resume"] ?: "true") == "true"
+ val applyPlaylist = (call.request.queryParameters["applyPlaylist"] ?: "true") == "true"
+ RemoteAccessServer.getInstance(appContext).service?.let { service ->
+ service.playlistManager.waitForConfirmation.value?.let { confirmation ->
+ scope.launch(Dispatchers.Main) {
+ if (resume) {
+ if (applyPlaylist) service.playlistManager.videoResumeStatus = ResumeStatus.ALWAYS
+ service.playlistManager.playIndex(
+ confirmation.index,
+ confirmation.flags,
+ forceResume = true
+ )
+ } else {
+ if (applyPlaylist) service.playlistManager.videoResumeStatus = ResumeStatus.NEVER
+ service.playlistManager.playIndex(
+ confirmation.index,
+ confirmation.flags,
+ forceRestart = true
+ )
+ }
+ }
+ service.playlistManager.waitForConfirmation.postValue(null)
+ }
+ service.playlistManager.waitForConfirmationAudio.value?.let { confirmation ->
+ scope.launch(Dispatchers.Main) {
+ if (resume) {
+ if (applyPlaylist) service.playlistManager.audioResumeStatus = ResumeStatus.ALWAYS
+ service.playlistManager.playIndex(
+ confirmation.index,
+ confirmation.flags,
+ forceResume = true
+ )
+ } else {
+ if (applyPlaylist) service.playlistManager.audioResumeStatus = ResumeStatus.NEVER
+ service.playlistManager.playIndex(
+ confirmation.index,
+ confirmation.flags,
+ forceRestart = true
+ )
+ }
+ }
+ service.playlistManager.waitForConfirmationAudio.postValue(null)
+ }
+ }
+ call.respond(HttpStatusCode.OK)
+ }
// Play a media
get("/play-all") {
val type = call.request.queryParameters["type"]
More information about the Android
mailing list