diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt index b12bf044..ff10e628 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt @@ -10,6 +10,7 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -22,7 +23,6 @@ import androidx.fragment.app.Fragment import eu.weblibre.flutter_mozilla_components.addons.WebExtensionPromptFeature import eu.weblibre.flutter_mozilla_components.databinding.FragmentBrowserBinding import eu.weblibre.flutter_mozilla_components.ext.getPreferenceKey -import eu.weblibre.flutter_mozilla_components.pip.PictureInPictureIntegration import eu.weblibre.flutter_mozilla_components.services.DownloadService import io.flutter.Log import mozilla.components.browser.state.selector.selectedTab @@ -35,6 +35,7 @@ import mozilla.components.feature.media.fullscreen.MediaSessionFullscreenFeature import mozilla.components.feature.privatemode.feature.SecureWindowFeature import mozilla.components.feature.prompts.PromptFeature import mozilla.components.feature.session.FullScreenFeature +import mozilla.components.feature.session.PictureInPictureFeature import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SwipeRefreshFeature import mozilla.components.feature.sitepermissions.SitePermissionsFeature @@ -61,7 +62,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit private val appLinksFeature = ViewBoundFeatureWrapper() private val promptFeature = ViewBoundFeatureWrapper() private val webExtensionPromptFeature = ViewBoundFeatureWrapper() - private val pictureInPictureIntegration = ViewBoundFeatureWrapper() private val sitePermissionsFeature = ViewBoundFeatureWrapper() private val swipeRefreshFeature = ViewBoundFeatureWrapper() private val secureWindowFeature = ViewBoundFeatureWrapper() @@ -69,6 +69,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit private val mediaSessionFullscreenFeature = ViewBoundFeatureWrapper() + private var pictureInPictureFeature: PictureInPictureFeature? = null + private val sessionId: String? get() = arguments?.getString(SESSION_ID_KEY) @@ -266,6 +268,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit sessionUseCases = components.useCases.sessionUseCases, tabId = sessionId, fullScreenChanged = ::fullScreenChanged, + viewportFitChanged = ::viewportFitChanged ), owner = this, view = binding.root, @@ -281,14 +284,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit view = binding.root, ) - pictureInPictureIntegration.set( - feature = PictureInPictureIntegration( - components.core.store, - requireActivity(), - sessionId, - ), - owner = this, - view = view, + pictureInPictureFeature = PictureInPictureFeature( + store = components.core.store, + activity = requireActivity(), + tabId = sessionId, ) secureWindowFeature.set( @@ -358,23 +357,23 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit } } + private fun viewportFitChanged(viewportFit: Int) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + activity?.window?.attributes?.layoutInDisplayCutoutMode = viewportFit + } + } + @CallSuper override fun onBackPressed(): Boolean { return backButtonHandler.any { it.onBackPressed() } } - final override fun onPause() { - pictureInPictureIntegration.get()?.onHomePressed() ?: false - super.onPause() - } + final override fun onHomePressed(): Boolean =pictureInPictureFeature?.onHomePressed() ?: false - final override fun onPictureInPictureModeChanged(enabled: Boolean) { - val session = components.core.store.state.selectedTab - val fullScreenMode = session?.content?.fullScreen ?: false - // If we're exiting PIP mode and we're in fullscreen mode, then we should exit fullscreen mode as well. - if (!enabled && fullScreenMode) { + override fun onPictureInPictureModeChanged(enabled: Boolean) { + pictureInPictureFeature?.onPictureInPictureModeChanged(enabled) + if (lifecycle.currentState == androidx.lifecycle.Lifecycle.State.CREATED) { onBackPressed() - fullScreenChanged(false) } } diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pip/PictureInPictureIntegration.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pip/PictureInPictureIntegration.kt deleted file mode 100644 index 254c1c0c..00000000 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/pip/PictureInPictureIntegration.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package eu.weblibre.flutter_mozilla_components.pip - -import android.app.Activity -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.cancel -import kotlinx.coroutines.flow.distinctUntilChangedBy -import kotlinx.coroutines.flow.mapNotNull -import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab -import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.feature.session.PictureInPictureFeature -import mozilla.components.lib.state.ext.flowScoped -import mozilla.components.support.base.feature.LifecycleAwareFeature - -class PictureInPictureIntegration( - private val store: BrowserStore, - activity: Activity, - private val customTabId: String?, - private val whiteList: List = listOf("youtube.com/tv"), -) : LifecycleAwareFeature { - private var scope: CoroutineScope? = null - private val pictureFeature = PictureInPictureFeature(store, activity) - private var whiteListed = false - - override fun start() { - scope = store.flowScoped { flow -> - flow.mapNotNull { state -> state.findTabOrCustomTabOrSelectedTab(customTabId) } - .distinctUntilChangedBy { it.content.url } - .collect { whiteListed = isWhitelisted(it.content.url) } - } - } - - override fun stop() { - scope?.cancel() - } - - fun onHomePressed() = if (whiteListed) { - pictureFeature.enterPipModeCompat() - } else { - pictureFeature.onHomePressed() - } - - private fun isWhitelisted(url: String): Boolean { - val exists = whiteList.firstOrNull { url.contains(it) } - return exists != null - } -}