1
0
Fork 0

Closes #778 - Progressive Web Apps! (#4914)

master
Tiger Oakes 2019-10-08 16:50:16 -07:00 committed by Sawyer Blatz
parent 0e435b8b7b
commit 78bc829735
9 changed files with 90 additions and 18 deletions

View File

@ -113,6 +113,12 @@
<data android:mimeType="text/plain" /> <data android:mimeType="text/plain" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="mozilla.components.feature.pwa.VIEW_PWA" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" />
</intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.ASSIST" /> <action android:name="android.intent.action.ASSIST" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />

View File

@ -49,4 +49,16 @@ object FeatureFlags {
* Gives option in Settings to disable auto play media * Gives option in Settings to disable auto play media
*/ */
val autoPlayMedia = nightly or debug val autoPlayMedia = nightly or debug
val granularDataDeletion = nightly or debug
/**
* Gives option in Settings to Delete Browsing Data on new menu option Quit
*/
val deleteDataOnQuit = nightly or debug
/**
* Allows Progressive Web Apps to be installed to the device home screen.
*/
val progressiveWebApps = nightly or debug
} }

View File

@ -32,12 +32,12 @@ class FindInPageIntegration(
} }
override fun onLaunch(view: View, feature: LifecycleAwareFeature) { override fun onLaunch(view: View, feature: LifecycleAwareFeature) {
store.state.findCustomTabOrSelectedTab(sessionId)?.let { session -> store.state.findCustomTabOrSelectedTab(sessionId)?.let { tab ->
if (session !is CustomTabSessionState) { if (tab is CustomTabSessionState) {
toolbar.visibility = View.GONE toolbar.visibility = View.GONE
} }
view.visibility = View.VISIBLE view.visibility = View.VISIBLE
(feature as FindInPageFeature).bind(session) (feature as FindInPageFeature).bind(tab)
view.layoutParams.height = toolbar.height view.layoutParams.height = toolbar.height
} }
} }

View File

@ -8,6 +8,8 @@ import android.content.Context
import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.SessionManager
import mozilla.components.feature.customtabs.CustomTabIntentProcessor import mozilla.components.feature.customtabs.CustomTabIntentProcessor
import mozilla.components.feature.intent.processing.TabIntentProcessor import mozilla.components.feature.intent.processing.TabIntentProcessor
import mozilla.components.feature.pwa.ManifestStorage
import mozilla.components.feature.pwa.intent.WebAppIntentProcessor
import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SessionUseCases
import org.mozilla.fenix.test.Mockable import org.mozilla.fenix.test.Mockable
@ -38,6 +40,7 @@ class IntentProcessors(
val externalAppIntentProcessors by lazy { val externalAppIntentProcessors by lazy {
listOf( listOf(
WebAppIntentProcessor(sessionManager, sessionUseCases.loadUrl, ManifestStorage(context)),
CustomTabIntentProcessor(sessionManager, sessionUseCases.loadUrl, context.resources) CustomTabIntentProcessor(sessionManager, sessionUseCases.loadUrl, context.resources)
) )
} }

View File

@ -18,6 +18,7 @@ import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.SettingsUseCases import mozilla.components.feature.session.SettingsUseCases
import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.tabs.TabsUseCases
import org.mozilla.fenix.FeatureFlags.progressiveWebApps
import org.mozilla.fenix.test.Mockable import org.mozilla.fenix.test.Mockable
/** /**
@ -55,7 +56,9 @@ class UseCases(
val appLinksUseCases by lazy { AppLinksUseCases(context.applicationContext) } val appLinksUseCases by lazy { AppLinksUseCases(context.applicationContext) }
val webAppUseCases by lazy { WebAppUseCases(context, sessionManager, httpClient, supportWebApps = false) } val webAppUseCases by lazy {
WebAppUseCases(context, sessionManager, httpClient, supportWebApps = progressiveWebApps)
}
val downloadUseCases by lazy { DownloadsUseCases(store) } val downloadUseCases by lazy { DownloadsUseCases(store) }

View File

@ -11,9 +11,9 @@ import mozilla.components.browser.menu.item.BrowserMenuHighlightableItem
import mozilla.components.browser.menu.item.BrowserMenuImageText import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.menu.item.BrowserMenuImageSwitch import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.ext.asActivity import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.theme.ThemeManager

View File

@ -5,8 +5,11 @@
package org.mozilla.fenix.customtabs package org.mozilla.fenix.customtabs
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import androidx.navigation.NavDirections
import mozilla.components.browser.session.runWithSession import mozilla.components.browser.session.runWithSession
import mozilla.components.concept.engine.manifest.WebAppManifestParser
import mozilla.components.feature.intent.ext.getSessionId import mozilla.components.feature.intent.ext.getSessionId
import mozilla.components.feature.pwa.ext.getWebAppManifest
import mozilla.components.support.utils.SafeIntent import mozilla.components.support.utils.SafeIntent
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
@ -23,6 +26,7 @@ import java.security.InvalidParameterException
* such as custom tabs and progressive web apps. * such as custom tabs and progressive web apps.
*/ */
open class ExternalAppBrowserActivity : HomeActivity() { open class ExternalAppBrowserActivity : HomeActivity() {
final override fun getBreadcrumbMessage(destination: NavDestination): String { final override fun getBreadcrumbMessage(destination: NavDestination): String {
val fragmentName = resources.getResourceEntryName(destination.id) val fragmentName = resources.getResourceEntryName(destination.id)
return "Changing to fragment $fragmentName, isCustomTab: true" return "Changing to fragment $fragmentName, isCustomTab: true"
@ -35,12 +39,20 @@ open class ExternalAppBrowserActivity : HomeActivity() {
override fun getNavDirections( override fun getNavDirections(
from: BrowserDirection, from: BrowserDirection,
customTabSessionId: String? customTabSessionId: String?
) = when (from) { ): NavDirections {
BrowserDirection.FromGlobal -> val manifest = intent
NavGraphDirections.actionGlobalExternalAppBrowser(customTabSessionId) .getWebAppManifest()
else -> throw InvalidParameterException( ?.let { WebAppManifestParser().serialize(it).toString() }
"Tried to navigate to ExternalAppBrowserFragment from $from" return when (from) {
) BrowserDirection.FromGlobal ->
NavGraphDirections.actionGlobalExternalAppBrowser(
activeSessionId = customTabSessionId,
webAppManifest = manifest
)
else -> throw InvalidParameterException(
"Tried to navigate to ExternalAppBrowserFragment from $from"
)
}
} }
final override fun createBrowsingModeManager(initialMode: BrowsingMode) = final override fun createBrowsingModeManager(initialMode: BrowsingMode) =

View File

@ -6,13 +6,20 @@ package org.mozilla.fenix.customtabs
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import androidx.core.view.isGone
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.component_search.* import kotlinx.android.synthetic.main.component_search.*
import kotlinx.android.synthetic.main.fragment_browser.view.* import kotlinx.android.synthetic.main.fragment_browser.view.*
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi import kotlinx.coroutines.ObsoleteCoroutinesApi
import mozilla.components.browser.session.Session import mozilla.components.browser.session.Session
import mozilla.components.concept.engine.manifest.WebAppManifestParser
import mozilla.components.concept.engine.manifest.getOrNull
import mozilla.components.feature.pwa.ext.getTrustedScope
import mozilla.components.feature.pwa.ext.trustedOrigins import mozilla.components.feature.pwa.ext.trustedOrigins
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.BackHandler import mozilla.components.support.base.feature.BackHandler
@ -32,6 +39,8 @@ import org.mozilla.fenix.ext.requireComponents
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler { class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler {
private val args by navArgs<ExternalAppBrowserFragmentArgs>()
private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>() private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
private val hideToolbarFeature = ViewBoundFeatureWrapper<WebAppHideToolbarFeature>() private val hideToolbarFeature = ViewBoundFeatureWrapper<WebAppHideToolbarFeature>()
@ -40,6 +49,11 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler {
val activity = requireActivity() val activity = requireActivity()
val components = activity.components val components = activity.components
val manifest = args.webAppManifest?.let { json ->
WebAppManifestParser().parse(json).getOrNull()
}
val trustedScopes = listOfNotNull(manifest?.getTrustedScope())
customTabSessionId?.let { customTabSessionId -> customTabSessionId?.let { customTabSessionId ->
customTabsIntegration.set( customTabsIntegration.set(
feature = CustomTabsIntegration( feature = CustomTabsIntegration(
@ -59,12 +73,31 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler {
requireComponents.core.sessionManager, requireComponents.core.sessionManager,
toolbar, toolbar,
customTabSessionId, customTabSessionId,
emptyList() trustedScopes
) { toolbarVisible -> ) { toolbarVisible ->
updateLayoutMargins(inFullScreen = !toolbarVisible) updateLayoutMargins(inFullScreen = !toolbarVisible)
}, },
owner = this, owner = this,
view = toolbar) view = toolbar)
if (manifest != null) {
activity.lifecycle.addObserver(
WebAppActivityFeature(
activity,
components.core.icons,
manifest
)
)
viewLifecycleOwner.lifecycle.addObserver(
WebAppSiteControlsFeature(
activity.applicationContext,
requireComponents.core.sessionManager,
requireComponents.useCases.sessionUseCases.reload,
customTabSessionId,
manifest
)
)
}
} }
consumeFrom(browserStore) { consumeFrom(browserStore) {
@ -121,8 +154,13 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler {
} }
override fun getEngineMargins(): Pair<Int, Int> { override fun getEngineMargins(): Pair<Int, Int> {
val toolbarSize = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height) val toolbarHidden = toolbar.isGone
return toolbarSize to 0 return if (toolbarHidden) {
0 to 0
} else {
val toolbarSize = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
toolbarSize to 0
}
} }
override fun getAppropriateLayoutGravity() = Gravity.TOP override fun getAppropriateLayoutGravity() = Gravity.TOP

View File

@ -198,10 +198,8 @@
android:id="@+id/externalAppBrowserFragment" android:id="@+id/externalAppBrowserFragment"
android:name="org.mozilla.fenix.customtabs.ExternalAppBrowserFragment" android:name="org.mozilla.fenix.customtabs.ExternalAppBrowserFragment"
tools:layout="@layout/fragment_browser"> tools:layout="@layout/fragment_browser">
<argument <argument android:name="activeSessionId" app:argType="string" app:nullable="true" />
android:name="activeSessionId" <argument android:name="webAppManifest" app:argType="string" app:nullable="true"/>
app:argType="string"
app:nullable="true" />
<action <action
android:id="@+id/action_externalAppBrowserFragment_to_shareFragment" android:id="@+id/action_externalAppBrowserFragment_to_shareFragment"
app:destination="@id/shareFragment" /> app:destination="@id/shareFragment" />