fix(android): disable controls when in PiP

This commit is contained in:
Krzysztof Moch
2025-11-06 09:02:40 +01:00
parent 649bc1c88e
commit 92c832864d
3 changed files with 23 additions and 4 deletions
@@ -91,6 +91,7 @@ class FullscreenVideoFragment(private val videoView: VideoView) : Fragment() {
requireActivity().isInPictureInPictureMode requireActivity().isInPictureInPictureMode
if (isInPictureInPictureMode) { if (isInPictureInPictureMode) {
// Disable controls in PiP mode - media session creates its own controls for PiP
videoView.playerView.useController = false videoView.playerView.useController = false
} else { } else {
videoView.playerView.useController = videoView.useController videoView.playerView.useController = videoView.useController
@@ -197,7 +198,11 @@ class FullscreenVideoFragment(private val videoView: VideoView) : Fragment() {
restoreSystemUI() restoreSystemUI()
if (videoView.useController == false) { // Keep controls disabled if in PiP mode - media session creates its own controls for PiP
val isInPictureInPictureMode = requireActivity().isInPictureInPictureMode
if (isInPictureInPictureMode) {
videoView.playerView.useController = false
} else if (videoView.useController == false) {
videoView.playerView.useController = false videoView.playerView.useController = false
} }
@@ -50,6 +50,9 @@ class PictureInPictureHelperFragment(private val videoView: VideoView) : Fragmen
} }
if (currentPipVideo == videoView) { if (currentPipVideo == videoView) {
// Disable controls immediately when entering PiP - media session creates its own controls for PiP
videoView.playerView.useController = false
// If we're currently in fullscreen, exit it first to prevent parent conflicts // If we're currently in fullscreen, exit it first to prevent parent conflicts
if (videoView.isInFullscreen) { if (videoView.isInFullscreen) {
try { try {
@@ -320,10 +320,9 @@ class VideoView @JvmOverloads constructor(
Log.d("ReactNativeVideo", "Hiding root content views for PiP video nitroId: $nitroId") Log.d("ReactNativeVideo", "Hiding root content views for PiP video nitroId: $nitroId")
// Remove playerView from parent // In PiP mode, disable controls immediately - media session creates its own controls for PiP
// In PiP mode, we don't want to show the controller
// Controls are handled by System if we have MediaSession
playerView.useController = false playerView.useController = false
playerView.setBackgroundColor(Color.BLACK) playerView.setBackgroundColor(Color.BLACK)
playerView.setShutterBackgroundColor(Color.BLACK) playerView.setShutterBackgroundColor(Color.BLACK)
@@ -412,6 +411,11 @@ class VideoView @JvmOverloads constructor(
return try { return try {
events.willEnterPictureInPicture?.let { it() } events.willEnterPictureInPicture?.let { it() }
// Disable controls before entering PiP - media session creates its own controls for PiP
runOnMainThread {
playerView.useController = false
}
val success = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val success = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val params = createPictureInPictureParams(this) val params = createPictureInPictureParams(this)
safeEnterPictureInPictureMode(params) safeEnterPictureInPictureMode(params)
@@ -447,6 +451,9 @@ class VideoView @JvmOverloads constructor(
events.willExitPictureInPicture?.let { it() } events.willExitPictureInPicture?.let { it() }
// Restore controls when exiting PiP - they were disabled because media session handles PiP controls
playerView.useController = useController
if (movedToRootForPiP) { if (movedToRootForPiP) {
restoreRootContentViews() restoreRootContentViews()
} else { } else {
@@ -471,6 +478,10 @@ class VideoView @JvmOverloads constructor(
} }
events.willExitPictureInPicture?.let { it() } events.willExitPictureInPicture?.let { it() }
// Restore controls when exiting PiP - they were disabled because media session handles PiP controls
playerView.useController = useController
if (movedToRootForPiP) { if (movedToRootForPiP) {
restoreRootContentViews() restoreRootContentViews()
} else { } else {