Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ package com.nextcloud.client.player.ui

import android.app.Activity
import android.app.PictureInPictureParams
import android.graphics.Rect
import android.os.Build
import android.util.Rational
import android.view.View
import com.nextcloud.client.player.media3.PlaybackModel
import com.nextcloud.client.player.model.state.VideoSize
import com.nextcloud.client.player.util.PlayerUtil.isPictureInPictureAllowed
Expand All @@ -26,42 +23,20 @@ class VideoPictureInPicture(private val activity: Activity, private val playback

private val defaultAspectRatio = Rational(ASPECT_RATIO_WIDTH, ASPECT_RATIO_HEIGHT)

val isAllowed: Boolean get() = activity.isPictureInPictureAllowed()
fun enter(): Boolean = activity.isPictureInPictureAllowed() && activity.enterPictureInPictureMode(createParams())

fun enter(sourceView: View): Boolean = isAllowed && activity.enterPictureInPictureMode(createParams(sourceView))

private fun createParams(sourceView: View): PictureInPictureParams {
val aspectRatio = getAspectRatio(playbackModel.state?.currentItemState?.videoSize)
return PictureInPictureParams.Builder().let {
it.setAspectRatio(aspectRatio)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
it.setAutoEnterEnabled(false)
}
it.setSourceRectHint(getSourceRectHint(sourceView, aspectRatio))
it.build()
}
}
private fun createParams(): PictureInPictureParams = PictureInPictureParams.Builder()
.setAspectRatio(getAspectRatio(playbackModel.state?.currentItemState?.videoSize))
.build()

private fun getAspectRatio(videoSize: VideoSize?): Rational {
if (videoSize == null) return defaultAspectRatio

val ratio = videoSize.width.toFloat() / videoSize.height.toFloat()
return if (ratio < MIN_ASPECT_RATIO || ratio > MAX_ASPECT_RATIO) {
return if (ratio !in MIN_ASPECT_RATIO..MAX_ASPECT_RATIO) {
defaultAspectRatio
} else {
Rational(videoSize.width, videoSize.height)
}
}

private fun getSourceRectHint(sourceView: View, aspectRatio: Rational): Rect {
val sourceRect = Rect()
sourceView.getGlobalVisibleRect(sourceRect)
val heightHint = (sourceRect.width() / aspectRatio.toFloat()).toInt()
return Rect(
sourceRect.left,
sourceRect.top + (sourceRect.height() - heightHint) / 2,
sourceRect.right,
sourceRect.top + (sourceRect.height() + heightHint) / 2
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ class PreviewImageActivity :
viewPager?.setCurrentItem(position, true)
}

fun enterPictureInPicture(): Boolean = viewPager?.let { pictureInPicture.enter(it) } == true
fun enterPictureInPicture(): Boolean = pictureInPicture.enter()

override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.activity.addCallback
import androidx.activity.trackPipAnimationHintView
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.snackbar.Snackbar
import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.client.jobs.BackgroundJobManager
Expand Down Expand Up @@ -127,7 +129,7 @@ class PreviewPlaybackFragment :
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = PreviewPlaybackFragmentBinding.inflate(inflater, container, false)
loadThumbnail()
registerPictureInPictureOnBack()
setupPictureInPicture()
binding.playerControlView.navigator = activity as? MediaNavigator
binding.playerControlView.addPaddingForNavBar()
binding.playerControlView.isVisible = previewActivity?.isActionBarVisible != false
Expand Down Expand Up @@ -266,7 +268,7 @@ class PreviewPlaybackFragment :
}
}

private fun registerPictureInPictureOnBack() {
private fun setupPictureInPicture() {
if (!MimeTypeUtil.isVideo(file)) {
return
}
Expand All @@ -275,6 +277,15 @@ class PreviewPlaybackFragment :
return
}

viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
requireActivity().trackPipAnimationHintView(binding.surfaceView)
}
}
registerPictureInPictureOnBack()
}

private fun registerPictureInPictureOnBack() {
pictureInPictureCallback = requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
enabled = false
Expand Down
Loading