From dd84281bf998bd6db108720f57354aed5da24ede Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 1 Apr 2025 09:55:32 +0200 Subject: [PATCH] fix: properly open current video from media notification --- .../services/AbstractPlayerService.kt | 30 ++++++++++++++----- .../services/OfflinePlayerService.kt | 8 +++-- .../libretube/services/OnlinePlayerService.kt | 1 - .../libretube/ui/activities/MainActivity.kt | 10 +++++-- .../libretube/util/NowPlayingNotification.kt | 12 ++------ 5 files changed, 39 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/github/libretube/services/AbstractPlayerService.kt b/app/src/main/java/com/github/libretube/services/AbstractPlayerService.kt index 3510bc181..419d8e994 100644 --- a/app/src/main/java/com/github/libretube/services/AbstractPlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/AbstractPlayerService.kt @@ -41,6 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext @UnstableApi abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySession.Callback { @@ -116,7 +117,9 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio START_SERVICE_ACTION -> { CoroutineScope(Dispatchers.IO).launch { onServiceCreated(args) - notificationProvider?.intentActivity = getIntentActivity() + withContext(Dispatchers.Main) { + updateNotification() + } if (::videoId.isInitialized) startPlayback() } @@ -185,6 +188,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio trackSelector?.updateParameters { setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, isAudioOnlyPlayer) } + updateNotification() } } } @@ -239,9 +243,24 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio } } + /** + * Trigger a notification update with an updated PendingIntent. + */ + private fun updateNotification() { + val notificationIntent = Intent(this, getIntentActivity()).apply { + putExtra(IntentData.maximizePlayer, true) + putExtra(IntentData.offlinePlayer, isOfflinePlayer) + putExtra(IntentData.audioOnly, isAudioOnlyPlayer) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + } + notificationProvider?.notificationIntent = notificationIntent + mediaLibrarySession?.let { + onUpdateNotification(it, true) + } + } + abstract val isOfflinePlayer: Boolean - abstract var isAudioOnlyPlayer: Boolean - open val maximizePlayer: Boolean = true + var isAudioOnlyPlayer: Boolean = false val watchPositionsEnabled get() = (PlayerHelper.watchPositionsAudio && isAudioOnlyPlayer) || (PlayerHelper.watchPositionsVideo && !isAudioOnlyPlayer) @@ -252,10 +271,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio override fun onCreate() { super.onCreate() - notificationProvider = NowPlayingNotification( - this, - offlinePlayer = isOfflinePlayer, - ) + notificationProvider = NowPlayingNotification(this) setMediaNotificationProvider(notificationProvider!!) createPlayerAndMediaSession() diff --git a/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt index f4d4f2c4b..64cedc107 100644 --- a/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OfflinePlayerService.kt @@ -26,6 +26,7 @@ import com.github.libretube.extensions.updateParameters import com.github.libretube.helpers.PlayerHelper import com.github.libretube.ui.activities.MainActivity import com.github.libretube.ui.activities.NoInternetActivity +import com.github.libretube.ui.activities.OfflinePlayerActivity import com.github.libretube.ui.fragments.DownloadTab import com.github.libretube.util.PlayingQueue import kotlinx.coroutines.CoroutineScope @@ -41,7 +42,6 @@ import kotlin.io.path.exists @OptIn(UnstableApi::class) open class OfflinePlayerService : AbstractPlayerService() { override val isOfflinePlayer: Boolean = true - override var isAudioOnlyPlayer: Boolean = true private var noInternetService: Boolean = false private var downloadWithItems: DownloadWithItems? = null @@ -94,7 +94,11 @@ open class OfflinePlayerService : AbstractPlayerService() { } override fun getIntentActivity(): Class<*> { - return if (noInternetService) NoInternetActivity::class.java else MainActivity::class.java + return when { + !noInternetService && isAudioOnlyPlayer -> MainActivity::class.java + noInternetService && isAudioOnlyPlayer -> NoInternetActivity::class.java + else -> OfflinePlayerActivity::class.java + } } /** diff --git a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt index a4e1d971a..8a56fd5e6 100644 --- a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt @@ -48,7 +48,6 @@ import java.io.IOException @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) open class OnlinePlayerService : AbstractPlayerService() { override val isOfflinePlayer: Boolean = false - override var isAudioOnlyPlayer: Boolean = false // PlaylistId/ChannelId for autoplay private var playlistId: String? = null diff --git a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt index 5d84eb748..73a2a6d08 100644 --- a/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/github/libretube/ui/activities/MainActivity.kt @@ -434,9 +434,13 @@ class MainActivity : BaseActivity() { } if (intent?.getBooleanExtra(IntentData.maximizePlayer, false) == true) { - // attempt to open the current player fragment first before creating a new one - // TODO: handle this differently - if (runOnPlayerFragment { binding.playerMotionLayout.transitionToStart(); true }) return + // attempt to open the current video player fragment + if (intent?.getBooleanExtra(IntentData.audioOnly, false) == false) { + runOnPlayerFragment { binding.playerMotionLayout.transitionToStart(); true } + return + } + + // if it's an audio only session, attempt to maximize the audio player or create a new one if (runOnAudioPlayerFragment { binding.playerMotionLayout.transitionToStart(); true }) return val offlinePlayer = intent!!.getBooleanExtra(IntentData.offlinePlayer, false) diff --git a/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt b/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt index 8ca23217a..25992bb4e 100644 --- a/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt +++ b/app/src/main/java/com/github/libretube/util/NowPlayingNotification.kt @@ -21,10 +21,8 @@ import com.google.common.collect.ImmutableList @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class) class NowPlayingNotification( private val context: Context, - private val offlinePlayer: Boolean = false + var notificationIntent: Intent = Intent(), ): MediaNotification.Provider { - var intentActivity: Class<*> = MainActivity::class.java - private val nProvider = DefaultMediaNotificationProvider.Builder(context) .setNotificationId(NotificationId.PLAYER_PLAYBACK.id) .setChannelId(PLAYER_CHANNEL_NAME) @@ -36,14 +34,10 @@ class NowPlayingNotification( // it doesn't start a completely new MainActivity because the MainActivity's launchMode // is set to "singleTop" in the AndroidManifest (important!!!) // that's the only way to launch back into the previous activity (e.g. the player view) - val intent = Intent(context, intentActivity).apply { - putExtra(IntentData.maximizePlayer, true) - putExtra(IntentData.offlinePlayer, offlinePlayer) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - } + return PendingIntentCompat - .getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, false) + .getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT, false) } /**