diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 9c099a0a4..eb4a4073b 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -49,6 +49,7 @@ import org.mozilla.fenix.components.toolbar.ToolbarComponent import org.mozilla.fenix.components.toolbar.ToolbarIntegration import org.mozilla.fenix.components.toolbar.ToolbarMenu import org.mozilla.fenix.components.toolbar.ToolbarUIView +import org.mozilla.fenix.customtabs.CustomTabsIntegration import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.share @@ -68,6 +69,8 @@ class BrowserFragment : Fragment(), BackHandler, ComponentCallbacks2 { private val sitePermissionsFeature = ViewBoundFeatureWrapper() private val fullScreenFeature = ViewBoundFeatureWrapper() private val thumbnailsFeature = ViewBoundFeatureWrapper() + private val customTabsIntegration = ViewBoundFeatureWrapper() + var sessionId: String? = null override fun onCreateView( @@ -216,6 +219,22 @@ class BrowserFragment : Fragment(), BackHandler, ComponentCallbacks2 { owner = this, view = view ) + + val actionEmitter = ActionBusFactory.get(this).getManagedEmitter(SearchAction::class.java) + sessionId?.let { id -> + customTabsIntegration.set( + feature = CustomTabsIntegration( + requireContext(), + requireComponents.core.sessionManager, + toolbar, + id, + requireActivity(), + onItemTapped = { actionEmitter.onNext(SearchAction.ToolbarMenuItemTapped(it)) } + ), + owner = this, + view = view + ) + } } override fun onResume() { diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt index 37b2e33d9..eee267e87 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt @@ -10,8 +10,6 @@ import mozilla.components.browser.menu.item.BrowserMenuDivider import mozilla.components.browser.menu.item.BrowserMenuImageText import mozilla.components.browser.menu.item.BrowserMenuItemToolbar import mozilla.components.browser.menu.item.BrowserMenuSwitch -import mozilla.components.browser.menu.item.SimpleBrowserMenuItem -import mozilla.components.browser.session.runWithSession import org.mozilla.fenix.DefaultThemeManager import org.mozilla.fenix.R import org.mozilla.fenix.ext.components @@ -109,128 +107,83 @@ class ToolbarMenu( BrowserMenuItemToolbar(listOf(back, forward, refresh)) } - private val isCustomTab by lazy { - context.components.core.sessionManager.runWithSession(sessionId) { - it.isCustomTabSession() - } - } - private val menuItems by lazy { - if (isCustomTab) { - listOf( - SimpleBrowserMenuItem( - context.getString(R.string.browser_menu_powered_by), - CAPTION_TEXT_SIZE, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ), - BrowserMenuDivider(), - SimpleBrowserMenuItem( - context.getString(R.string.browser_menu_open_in_fenix), - textColorResource = DefaultThemeManager.resolveAttribute( - R.attr.browserToolbarMenuIcons, - context - ) - ) { - onItemTapped.invoke(Item.OpenInFenix) - }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_find_in_page), - R.drawable.mozac_ic_search, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.FindInPage) - }, - BrowserMenuSwitch(context.getString(R.string.browser_menu_desktop_site), - requestDesktopStateProvider, { checked -> - onItemTapped.invoke(Item.RequestDesktop(checked)) - }), - BrowserMenuImageText( - context.getString(R.string.browser_menu_share), - R.drawable.mozac_ic_share, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.Share) - }, - menuToolbar - ) - } else { - listOf( - BrowserMenuImageText( - context.getString(R.string.browser_menu_help), - R.drawable.ic_help, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.Help) - }, + listOf( + BrowserMenuImageText( + context.getString(R.string.browser_menu_help), + R.drawable.ic_help, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.Help) + }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_settings), - R.drawable.ic_settings, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.Settings) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_settings), + R.drawable.ic_settings, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.Settings) + }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_library), - R.drawable.ic_library, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.Library) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_library), + R.drawable.ic_library, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.Library) + }, - BrowserMenuDivider(), + BrowserMenuDivider(), - BrowserMenuSwitch(context.getString(R.string.browser_menu_desktop_site), - requestDesktopStateProvider, { checked -> - onItemTapped.invoke(Item.RequestDesktop(checked)) - }), + BrowserMenuSwitch(context.getString(R.string.browser_menu_desktop_site), + requestDesktopStateProvider, { checked -> + onItemTapped.invoke(Item.RequestDesktop(checked)) + }), - BrowserMenuImageText( - context.getString(R.string.browser_menu_find_in_page), - R.drawable.mozac_ic_search, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.FindInPage) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_find_in_page), + R.drawable.mozac_ic_search, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.FindInPage) + }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_private_tab), - R.drawable.ic_private_browsing, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.NewPrivateTab) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_private_tab), + R.drawable.ic_private_browsing, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.NewPrivateTab) + }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_new_tab), - R.drawable.ic_new, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.NewTab) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_new_tab), + R.drawable.ic_new, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.NewTab) + }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_share), - R.drawable.mozac_ic_share, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.Share) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_share), + R.drawable.mozac_ic_share, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.Share) + }, - BrowserMenuImageText( - context.getString(R.string.browser_menu_report_issue), - R.drawable.ic_report_issues, - DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) - ) { - onItemTapped.invoke(Item.ReportIssue) - }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_report_issue), + R.drawable.ic_report_issues, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(Item.ReportIssue) + }, - BrowserMenuDivider(), + BrowserMenuDivider(), - menuToolbar - ) - } + menuToolbar + ) } companion object { diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt b/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt new file mode 100644 index 000000000..de96cc1b2 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt @@ -0,0 +1,162 @@ +/* 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.app.Activity +import android.content.Context +import mozilla.components.browser.menu.BrowserMenuBuilder +import mozilla.components.browser.menu.item.BrowserMenuDivider +import mozilla.components.browser.menu.item.BrowserMenuImageText +import mozilla.components.browser.menu.item.BrowserMenuItemToolbar +import mozilla.components.browser.menu.item.BrowserMenuSwitch +import mozilla.components.browser.menu.item.SimpleBrowserMenuItem +import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.toolbar.BrowserToolbar +import mozilla.components.feature.customtabs.CustomTabsToolbarFeature +import mozilla.components.support.base.feature.BackHandler +import mozilla.components.support.base.feature.LifecycleAwareFeature +import org.mozilla.fenix.DefaultThemeManager +import org.mozilla.fenix.R +import org.mozilla.fenix.components.toolbar.ToolbarMenu +import org.mozilla.fenix.ext.components + +class CustomTabsIntegration( + context: Context, + sessionManager: SessionManager, + toolbar: BrowserToolbar, + sessionId: String, + activity: Activity?, + onItemTapped: (ToolbarMenu.Item) -> Unit = {} + +) : LifecycleAwareFeature, BackHandler { + private val session = sessionManager.findSessionById(sessionId) + + val menuBuilder by lazy { BrowserMenuBuilder(menuItems) } + + val menuToolbar by lazy { + val back = BrowserMenuItemToolbar.TwoStateButton( + primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_back, + primaryContentDescription = context.getString(R.string.browser_menu_back), + primaryImageTintResource = DefaultThemeManager.resolveAttribute( + R.attr.browserToolbarMenuIcons, + context + ), + isInPrimaryState = { + context.components.core.sessionManager.selectedSession?.canGoBack ?: true + }, + secondaryImageTintResource = DefaultThemeManager.resolveAttribute( + R.attr.disabledIconColor, + context + ), + disableInSecondaryState = true + ) { + onItemTapped.invoke(ToolbarMenu.Item.Back) + } + + val forward = BrowserMenuItemToolbar.TwoStateButton( + primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_forward, + primaryContentDescription = context.getString(R.string.browser_menu_forward), + primaryImageTintResource = DefaultThemeManager.resolveAttribute( + R.attr.browserToolbarMenuIcons, + context + ), + isInPrimaryState = { + context.components.core.sessionManager.selectedSession?.canGoForward ?: true + }, + secondaryImageTintResource = DefaultThemeManager.resolveAttribute( + R.attr.disabledIconColor, + context + ), + disableInSecondaryState = true + ) { + onItemTapped.invoke(ToolbarMenu.Item.Forward) + } + + val refresh = BrowserMenuItemToolbar.TwoStateButton( + primaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_refresh, + primaryContentDescription = context.getString(R.string.browser_menu_refresh), + primaryImageTintResource = DefaultThemeManager.resolveAttribute( + R.attr.browserToolbarMenuIcons, + context + ), + isInPrimaryState = { + val loading = context.components.core.sessionManager.selectedSession?.loading + loading == false + }, + secondaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_stop, + secondaryContentDescription = context.getString(R.string.browser_menu_stop), + secondaryImageTintResource = DefaultThemeManager.resolveAttribute( + R.attr.browserToolbarMenuIcons, + context + ), + disableInSecondaryState = false + ) { + if (context.components.core.sessionManager.selectedSession?.loading == true) { + onItemTapped.invoke(ToolbarMenu.Item.Stop) + } else { + onItemTapped.invoke(ToolbarMenu.Item.Reload) + } + } + + BrowserMenuItemToolbar(listOf(back, forward, refresh)) + } + + private val menuItems by lazy { + listOf( + SimpleBrowserMenuItem( + context.getString(R.string.browser_menu_powered_by), + ToolbarMenu.CAPTION_TEXT_SIZE, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ), + BrowserMenuDivider(), + SimpleBrowserMenuItem( + context.getString(R.string.browser_menu_open_in_fenix), + textColorResource = DefaultThemeManager.resolveAttribute( + R.attr.browserToolbarMenuIcons, + context + ) + ) { + onItemTapped.invoke(ToolbarMenu.Item.OpenInFenix) + }, + BrowserMenuImageText( + context.getString(R.string.browser_menu_find_in_page), + R.drawable.mozac_ic_search, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(ToolbarMenu.Item.FindInPage) + }, + BrowserMenuSwitch(context.getString(R.string.browser_menu_desktop_site), + { session?.desktopMode ?: false }, { checked -> + onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) + }), + BrowserMenuImageText( + context.getString(R.string.browser_menu_share), + R.drawable.mozac_ic_share, + DefaultThemeManager.resolveAttribute(R.attr.browserToolbarMenuIcons, context) + ) { + onItemTapped.invoke(ToolbarMenu.Item.Share) + }, + menuToolbar + ) + } + private val feature = CustomTabsToolbarFeature( + sessionManager, + toolbar, + sessionId, + menuBuilder, + closeListener = { activity?.finish() }) + + override fun start() { + feature.start() + } + + override fun stop() { + feature.stop() + } + + override fun onBackPressed(): Boolean { + return feature.onBackPressed() + } +}