1
0
Fork 0
fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt

201 lines
8.5 KiB
Kotlin
Raw Normal View History

2019-08-12 18:31:59 +02:00
/* 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 org.mozilla.fenix.customtabs
import android.content.Context
2019-08-12 18:31:59 +02:00
import android.view.View
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.component_browser_top_toolbar.*
2019-08-12 18:31:59 +02:00
import kotlinx.android.synthetic.main.fragment_browser.view.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.browser.session.Session
import mozilla.components.concept.engine.manifest.WebAppManifestParser
import mozilla.components.concept.engine.manifest.getOrNull
import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.customtabs.CustomTabWindowFeature
import mozilla.components.feature.pwa.ext.getTrustedScope
import mozilla.components.feature.pwa.ext.trustedOrigins
2019-11-07 20:30:03 +01:00
import mozilla.components.feature.pwa.feature.ManifestUpdateFeature
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
2019-10-02 06:45:04 +02:00
import mozilla.components.feature.session.TrackingProtectionUseCases
2019-08-12 18:31:59 +02:00
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler
2019-08-12 18:31:59 +02:00
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
2019-11-07 20:30:03 +01:00
import mozilla.components.support.ktx.android.arch.lifecycle.addObservers
2019-08-12 18:31:59 +02:00
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BaseBrowserFragment
import org.mozilla.fenix.browser.CustomTabContextMenuCandidate
import org.mozilla.fenix.browser.FenixSnackbarDelegate
import org.mozilla.fenix.ext.components
2019-08-12 18:31:59 +02:00
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
2019-08-12 18:31:59 +02:00
/**
* Fragment used for browsing the web within external apps.
*/
@ExperimentalCoroutinesApi
class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
2019-08-12 18:31:59 +02:00
private val args by navArgs<ExternalAppBrowserFragmentArgs>()
2019-08-12 18:31:59 +02:00
private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
private val windowFeature = ViewBoundFeatureWrapper<CustomTabWindowFeature>()
private val hideToolbarFeature = ViewBoundFeatureWrapper<WebAppHideToolbarFeature>()
2019-08-12 18:31:59 +02:00
@Suppress("LongMethod")
2019-08-12 18:31:59 +02:00
override fun initializeUI(view: View): Session? {
return super.initializeUI(view)?.also {
val activity = requireActivity()
val components = activity.components
2019-08-12 18:31:59 +02:00
val manifest = args.webAppManifest?.let { json ->
WebAppManifestParser().parse(json).getOrNull()
}
val trustedScopes = listOfNotNull(manifest?.getTrustedScope())
2019-08-12 18:31:59 +02:00
customTabSessionId?.let { customTabSessionId ->
customTabsIntegration.set(
feature = CustomTabsIntegration(
4281 remove qab (#6310) * For #4281: small ToolbarMenu refactor This makes it easier to see how items are ordered in the menuItems list * For 4281: add QAB buttons to menu * For 4281: removed menu back button per mocks I double checked with UX, and we'll be relying on the hardware back button for its functionality * For 4281: add content descriptions for bookmarking * For 4281: updated BrowserToolbarController for new functionality * For 4281: provided simple dependencies to browser controller More complex changes will be in a following commit, for review readability * For 4281: move toolbar controller dependencies up to BaseBrowserFragment The functionality they control is being moved into the toolbar menu, which is shared by both normal tabs and custom ones * For 4281: removed (now unused) code related to QAB * For 4281: fix test compilation after QAB removal Tests still need to be expanded to include added functionality * For 4281: updated menu to show if url is bookmarked This sloppy workaround is required because TwoStateButton requires that `isInPrimaryState` be a synchronous call, and checking whether or not the current site is bookmarked is quite slow (10-50 MS, in my tests). After days of work and many attempted solutions, this was the least abhorrent among them. https://github.com/mozilla-mobile/android-components/issues/4915 was opened against AC to evaluate potentially supporting async `isInPrimaryState` functions. https://github.com/mozilla-mobile/fenix/issues/6370 was opened against Fenix to investigate the unexpectedly slow call to `BookmarkStorage`. * For 4281: update reader mode switch * For 4281: selectively show/hide menu items * For 4281: add reader mode appearance * For 4281: update bookmark button when it is clicked * For 4281: removed unused QAB code * For 4281: removed QAB robot, updated UI tests * For 4281: removed QuickActionSheet metrics Since this behavior now lives in the toolbar, it is tracked via Event.BrowserMenuItemTapped * For 4281: fixed lint errors * For 4281: add new strings for buttons added to menu This is necessary because the location change (from QAB to toolbar menu) could affect the grammar in some languages * For 4281: remove outdated TODOs * For 4281: removed QAB container * For 4281: removed back button reference from UI test This button no longer exists * For 4821: Fixes a visual defect (extra padding on top of toolbar) * For 4281: update copy on reader mode * For 4281: fixed review nits
2019-11-12 02:10:14 +01:00
sessionManager = requireComponents.core.sessionManager,
toolbar = toolbar,
sessionId = customTabSessionId,
activity = activity,
engineLayout = view.swipeRefresh,
onItemTapped = { browserInteractor.onBrowserToolbarMenuItemTapped(it) },
isPrivate = requireComponents.browsingModeManager.mode.isPrivate,
shouldReverseItems = !activity.settings().shouldUseBottomToolbar
2019-08-12 18:31:59 +02:00
),
owner = this,
view = view
)
windowFeature.set(
feature = CustomTabWindowFeature(
activity,
components.core.store,
customTabSessionId
),
owner = this,
view = view
)
hideToolbarFeature.set(
feature = WebAppHideToolbarFeature(
requireComponents.core.sessionManager,
toolbar,
customTabSessionId,
trustedScopes
) { toolbarVisible ->
updateLayoutMargins(inFullScreen = !toolbarVisible)
},
owner = this,
view = toolbar
)
if (manifest != null) {
2019-11-07 20:30:03 +01:00
activity.lifecycle.addObservers(
WebAppActivityFeature(
activity,
components.core.icons,
manifest
2019-11-07 20:30:03 +01:00
),
ManifestUpdateFeature(
activity.applicationContext,
requireComponents.core.sessionManager,
2019-11-07 22:30:37 +01:00
requireComponents.core.webAppShortcutManager,
2019-11-07 20:30:03 +01:00
requireComponents.core.webAppManifestStorage,
customTabSessionId,
manifest
)
)
viewLifecycleOwner.lifecycle.addObserver(
WebAppSiteControlsFeature(
activity.applicationContext,
requireComponents.core.sessionManager,
requireComponents.useCases.sessionUseCases.reload,
customTabSessionId,
manifest
)
)
} else {
viewLifecycleOwner.lifecycle.addObserver(
PoweredByNotification(
activity.applicationContext,
requireComponents.core.store,
customTabSessionId
)
)
}
2019-08-12 18:31:59 +02:00
}
4281 remove qab (#6310) * For #4281: small ToolbarMenu refactor This makes it easier to see how items are ordered in the menuItems list * For 4281: add QAB buttons to menu * For 4281: removed menu back button per mocks I double checked with UX, and we'll be relying on the hardware back button for its functionality * For 4281: add content descriptions for bookmarking * For 4281: updated BrowserToolbarController for new functionality * For 4281: provided simple dependencies to browser controller More complex changes will be in a following commit, for review readability * For 4281: move toolbar controller dependencies up to BaseBrowserFragment The functionality they control is being moved into the toolbar menu, which is shared by both normal tabs and custom ones * For 4281: removed (now unused) code related to QAB * For 4281: fix test compilation after QAB removal Tests still need to be expanded to include added functionality * For 4281: updated menu to show if url is bookmarked This sloppy workaround is required because TwoStateButton requires that `isInPrimaryState` be a synchronous call, and checking whether or not the current site is bookmarked is quite slow (10-50 MS, in my tests). After days of work and many attempted solutions, this was the least abhorrent among them. https://github.com/mozilla-mobile/android-components/issues/4915 was opened against AC to evaluate potentially supporting async `isInPrimaryState` functions. https://github.com/mozilla-mobile/fenix/issues/6370 was opened against Fenix to investigate the unexpectedly slow call to `BookmarkStorage`. * For 4281: update reader mode switch * For 4281: selectively show/hide menu items * For 4281: add reader mode appearance * For 4281: update bookmark button when it is clicked * For 4281: removed unused QAB code * For 4281: removed QAB robot, updated UI tests * For 4281: removed QuickActionSheet metrics Since this behavior now lives in the toolbar, it is tracked via Event.BrowserMenuItemTapped * For 4281: fixed lint errors * For 4281: add new strings for buttons added to menu This is necessary because the location change (from QAB to toolbar menu) could affect the grammar in some languages * For 4281: remove outdated TODOs * For 4281: removed QAB container * For 4281: removed back button reference from UI test This button no longer exists * For 4821: Fixes a visual defect (extra padding on top of toolbar) * For 4281: update copy on reader mode * For 4281: fixed review nits
2019-11-12 02:10:14 +01:00
consumeFrom(browserFragmentStore) {
2019-08-12 18:31:59 +02:00
browserToolbarView.update(it)
}
consumeFrom(components.core.customTabsStore) { state ->
getSessionById()
?.let { session -> session.customTabConfig?.sessionToken }
?.let { token -> state.tabs[token] }
?.let { tabState ->
hideToolbarFeature.withFeature {
it.onTrustedScopesChange(tabState.trustedOrigins)
}
}
}
2019-08-12 18:31:59 +02:00
}
}
override fun removeSessionIfNeeded(): Boolean {
return customTabsIntegration.onBackPressed() || super.removeSessionIfNeeded()
}
override fun navToQuickSettingsSheet(session: Session, sitePermissions: SitePermissions?) {
val directions = ExternalAppBrowserFragmentDirections
.actionExternalAppBrowserFragmentToQuickSettingsSheetDialogFragment(
sessionId = session.id,
url = session.url,
title = session.title,
2019-08-12 18:31:59 +02:00
isSecured = session.securityInfo.secure,
sitePermissions = sitePermissions,
2020-01-31 13:27:48 +01:00
gravity = getAppropriateLayoutGravity(),
certificateName = session.securityInfo.issuer
2019-08-12 18:31:59 +02:00
)
nav(R.id.externalAppBrowserFragment, directions)
}
2019-09-10 22:29:21 +02:00
override fun navToTrackingProtectionPanel(session: Session) {
2019-10-02 06:45:04 +02:00
val useCase = TrackingProtectionUseCases(
sessionManager = requireComponents.core.sessionManager,
engine = requireComponents.core.engine
)
useCase.containsException(session) { contains ->
val isEnabled = session.trackerBlockingEnabled && !contains
val directions =
ExternalAppBrowserFragmentDirections
.actionExternalAppBrowserFragmentToTrackingProtectionPanelDialogFragment(
sessionId = session.id,
url = session.url,
trackingProtectionEnabled = isEnabled,
gravity = getAppropriateLayoutGravity()
)
nav(R.id.externalAppBrowserFragment, directions)
}
2019-09-10 22:29:21 +02:00
}
override fun getContextMenuCandidates(
context: Context,
view: View
): List<ContextMenuCandidate> = CustomTabContextMenuCandidate.defaultCandidates(
context,
context.components.useCases.contextMenuUseCases,
view,
FenixSnackbarDelegate(view)
)
2019-08-12 18:31:59 +02:00
}