1
0
Fork 0

For #2818 - Adds Picture-in-Picture feature

master
ekager 2020-04-06 22:15:04 -07:00 committed by Emily Kager
parent d3a5fe5eb4
commit 56eb2ec1d7
4 changed files with 91 additions and 34 deletions

View File

@ -72,6 +72,8 @@
android:name=".HomeActivity"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize|layoutDirection|smallestScreenSize|screenLayout"
android:launchMode="singleTask"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@ -106,6 +108,8 @@
android:label="@string/app_name"
android:persistableMode="persistNever"
android:taskAffinity=""
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<activity

View File

@ -48,4 +48,9 @@ object FeatureFlags {
* https://github.com/mozilla-mobile/fenix/issues/9059
*/
val webPushIntegration = Config.channel.isNightlyOrDebug
/**
* Enables picture-in-picture feature
*/
val pictureInPicture = Config.channel.isNightlyOrDebug
}

View File

@ -219,6 +219,16 @@ open class HomeActivity : LocaleAwareAppCompatActivity() {
super.onBackPressed()
}
final override fun onUserLeaveHint() {
supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach {
if (it is UserInteractionHandler && it.onHomePressed()) {
return
}
}
super.onUserLeaveHint()
}
protected open fun getBreadcrumbMessage(destination: NavDestination): String {
val fragmentName = resources.getResourceEntryName(destination.id)
return "Changing to fragment $fragmentName, isCustomTab: false"

View File

@ -31,6 +31,7 @@ import kotlinx.coroutines.withContext
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.session.runWithSessionIdOrSelected
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.feature.accounts.FxaCapability
import mozilla.components.feature.accounts.FxaWebChannelFeature
@ -45,6 +46,7 @@ import mozilla.components.feature.prompts.PromptFeature
import mozilla.components.feature.prompts.share.ShareDelegate
import mozilla.components.feature.readerview.ReaderViewFeature
import mozilla.components.feature.session.FullScreenFeature
import mozilla.components.feature.session.PictureInPictureFeature
import mozilla.components.feature.session.SessionFeature
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.SwipeRefreshFeature
@ -123,6 +125,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
private val swipeRefreshFeature = ViewBoundFeatureWrapper<SwipeRefreshFeature>()
private val webchannelIntegration = ViewBoundFeatureWrapper<FxaWebChannelFeature>()
private val sitePermissionWifiIntegration = ViewBoundFeatureWrapper<SitePermissionsWifiIntegration>()
private var pipFeature: PictureInPictureFeature? = null
var customTabSessionId: String? = null
@ -324,6 +327,15 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
view = view
)
if (FeatureFlags.pictureInPicture) {
pipFeature = PictureInPictureFeature(
requireComponents.core.sessionManager,
requireActivity(),
customTabSessionId,
::pipModeChanged
)
}
appLinksFeature.set(
feature = AppLinksFeature(
context,
@ -423,39 +435,9 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
feature = FullScreenFeature(
sessionManager,
SessionUseCases(sessionManager),
customTabSessionId
) { inFullScreen ->
if (inFullScreen) {
FenixSnackbar.make(
view = view,
duration = Snackbar.LENGTH_SHORT,
isDisplayedOnBrowserFragment = true
)
.setText(getString(R.string.full_screen_notification))
.show()
activity?.enterToImmersiveMode()
browserToolbarView.view.visibility = View.GONE
if (FeatureFlags.dynamicBottomToolbar) {
engineView.setDynamicToolbarMaxHeight(0)
browserToolbarView.expand()
// Without this, fullscreen has a margin at the top.
engineView.setVerticalClipping(0)
}
} else {
activity?.exitImmersiveModeIfNeeded()
(activity as? HomeActivity)?.let { activity ->
activity.themeManager.applyStatusBarTheme(activity)
}
browserToolbarView.view.visibility = View.VISIBLE
if (FeatureFlags.dynamicBottomToolbar) {
engineView.setDynamicToolbarMaxHeight(toolbarHeight)
}
}
if (!FeatureFlags.dynamicBottomToolbar) {
updateLayoutMargins(inFullScreen)
}
},
customTabSessionId,
::fullScreenChanged
),
owner = this,
view = view
)
@ -593,7 +575,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
if (findNavController().currentDestination?.id != R.id.searchFragment) {
view?.hideKeyboard()
}
fullScreenFeature.onBackPressed()
}
@CallSuper
@ -813,6 +794,63 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
}
}
override fun onHomePressed(): Boolean {
if (pipFeature?.onHomePressed() == true) {
return true
}
return false
}
private fun pipModeChanged(enabled: Boolean) {
val fullScreenMode =
requireComponents.core.sessionManager.runWithSessionIdOrSelected(customTabSessionId) { session ->
session.fullScreenMode
}
// If we're exiting PIP mode and we're in fullscreen mode, then we should exit fullscreen mode as well.
if (!enabled && fullScreenMode) {
onBackPressed()
fullScreenChanged(false)
}
}
final override fun onPictureInPictureModeChanged(enabled: Boolean) {
pipFeature?.onPictureInPictureModeChanged(enabled)
}
private fun fullScreenChanged(inFullScreen: Boolean) {
if (inFullScreen) {
FenixSnackbar.make(
view = view!!,
duration = Snackbar.LENGTH_SHORT,
isDisplayedOnBrowserFragment = true
)
.setText(getString(R.string.full_screen_notification))
.show()
activity?.enterToImmersiveMode()
browserToolbarView.view.visibility = View.GONE
if (FeatureFlags.dynamicBottomToolbar) {
engineView.setDynamicToolbarMaxHeight(0)
browserToolbarView.expand()
// Without this, fullscreen has a margin at the top.
engineView.setVerticalClipping(0)
}
} else {
activity?.exitImmersiveModeIfNeeded()
(activity as? HomeActivity)?.let { activity ->
activity.themeManager.applyStatusBarTheme(activity)
}
browserToolbarView.view.visibility = View.VISIBLE
if (FeatureFlags.dynamicBottomToolbar) {
val toolbarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
engineView.setDynamicToolbarMaxHeight(toolbarHeight)
}
}
if (!FeatureFlags.dynamicBottomToolbar) {
updateLayoutMargins(inFullScreen)
}
}
/*
* Dereference these views when the fragment view is destroyed to prevent memory leaks
*/