From 14ab4463dc54e84c7681aab12869ae5ce8fe33ce Mon Sep 17 00:00:00 2001 From: "Artem Y." Date: Wed, 14 Aug 2024 14:52:14 +0300 Subject: [PATCH 1/2] [ZEUS-4778] Prevent crash caused by double unbinding of service --- .../bitmovin/BitmovinVideoPlayerPlugin.kt | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt b/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt index 4ec2d14..0df076c 100644 --- a/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt +++ b/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt @@ -53,6 +53,7 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { private var playerConfig = VideoPlayerConfig() private var playerBind: Player? = null private val fullscreen = mutableStateOf(false) + private var isServiceBound = false override fun setup(config: VideoPlayerConfig) { playerConfig.playbackConfig.autoplayEnabled = config.playbackConfig.autoplayEnabled @@ -72,7 +73,7 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { RequestMissingPermissions() } else { // Bind and start the Background service without permissions - backgroundService(true, LocalContext.current) + bindAndStartBackgroundService(LocalContext.current) } } @@ -127,8 +128,7 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { } override fun onDestroy(owner: LifecycleOwner) { if (playerConfig.playbackConfig.backgroundPlaybackEnabled) { - // Stop and unbind the Background service - backgroundService(false, context) + unbindAndStopBackgroundService(context) } } } @@ -210,7 +210,7 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { val context = LocalContext.current val permissionState = rememberPermissionState(permission = Manifest.permission.POST_NOTIFICATIONS) { granted -> if (granted) { - backgroundService(true, context) + bindAndStartBackgroundService(context) } } if (!permissionState.status.isGranted) { @@ -219,29 +219,34 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { block = { permissionState.launchPermissionRequest() } ) } else { - // Bind and start the Background service - backgroundService(true, context) + bindAndStartBackgroundService(context) } } - private fun backgroundService(start: Boolean, context: Context) { + private fun bindAndStartBackgroundService(context: Context) { val intent = Intent(context, BackgroundPlaybackService::class.java) - if (start) { - if (BackgroundPlaybackService.isRunning) { - context.stopService(intent) - } - context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) - context.startService(intent) - } else { + if (BackgroundPlaybackService.isRunning) { context.stopService(intent) - context.unbindService(mConnection) } + context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) + context.startService(intent) + } + + private fun unbindAndStopBackgroundService(context: Context) { + if (!isServiceBound) return + + val intent = Intent(context, BackgroundPlaybackService::class.java) + + context.unbindService(mConnection) + context.stopService(intent) + isServiceBound = false } /** * Defines callbacks for service binding, passed to bindService() */ private val mConnection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, service: IBinder) { // We've bound to the Service, cast the IBinder and get the Player instance val binder = service as BackgroundPlaybackService.BackgroundBinder @@ -254,9 +259,11 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { playerView?.player = playerBind initializePlayer(this@BitmovinVideoPlayerPlugin.hlsUrl) + isServiceBound = true } override fun onServiceDisconnected(arg0: ComponentName) { + isServiceBound = false } } From d699cb3c8605f83b7ce0dc347ec076d88bdcb200 Mon Sep 17 00:00:00 2001 From: "Artem Y." Date: Wed, 14 Aug 2024 16:17:46 +0300 Subject: [PATCH 2/2] [ZEUS-4391] Wrap service bind and unbind calls into try-catch --- .../bitmovin/BitmovinVideoPlayerPlugin.kt | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt b/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt index 0df076c..4929ec2 100644 --- a/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt +++ b/playback-sdk-android/src/main/java/com/streamamg/player/plugin/bitmovin/BitmovinVideoPlayerPlugin.kt @@ -225,11 +225,16 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { private fun bindAndStartBackgroundService(context: Context) { val intent = Intent(context, BackgroundPlaybackService::class.java) - if (BackgroundPlaybackService.isRunning) { - context.stopService(intent) + + try { + if (BackgroundPlaybackService.isRunning) { + context.stopService(intent) + } + context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) + context.startService(intent) + } catch (e: Exception) { + e.printStackTrace() } - context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) - context.startService(intent) } private fun unbindAndStopBackgroundService(context: Context) { @@ -237,9 +242,13 @@ class BitmovinVideoPlayerPlugin : VideoPlayerPlugin { val intent = Intent(context, BackgroundPlaybackService::class.java) - context.unbindService(mConnection) - context.stopService(intent) - isServiceBound = false + try { + context.unbindService(mConnection) + context.stopService(intent) + isServiceBound = false + } catch (e: Exception) { + e.printStackTrace() + } } /**