External source support

Adds handling of information about external referrer (package, category)
when dealing with external intents.
upstream-sync
Grisha Kruglov 3 years ago committed by Grisha Kruglov
parent 2ac5a38120
commit ec98db4e54

@ -813,7 +813,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
components.useCases.searchUseCases.newTabSearch
.invoke(
searchTermOrURL,
SessionState.Source.USER_ENTERED,
SessionState.Source.Internal.UserEntered,
true,
mode.isPrivate,
searchEngine = engine

@ -6,10 +6,14 @@ package org.mozilla.fenix
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.StrictMode
import androidx.annotation.VisibleForTesting
import mozilla.components.feature.intent.processing.IntentProcessor
import mozilla.components.support.utils.EXTRA_ACTIVITY_REFERRER_CATEGORY
import mozilla.components.support.utils.EXTRA_ACTIVITY_REFERRER_PACKAGE
import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE
import org.mozilla.fenix.components.IntentProcessorType
import org.mozilla.fenix.components.getType
@ -54,6 +58,8 @@ class IntentReceiverActivity : Activity() {
components.analytics.metrics.track(Event.OpenedLink(Event.OpenedLink.Mode.NORMAL))
}
addReferrerInformation(intent)
val processor = getIntentProcessors(private).firstOrNull { it.process(intent) }
val intentProcessorType = components.intentProcessors.getType(processor)
@ -96,6 +102,28 @@ class IntentReceiverActivity : Activity() {
modeDependentProcessors +
NewTabShortcutIntentProcessor()
}
private fun addReferrerInformation(intent: Intent) {
// Pass along referrer information when possible.
// Referrer is supported for API>=22.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
return
}
// NB: referrer can be spoofed by the calling application. Use with caution.
val r = referrer ?: return
intent.putExtra(EXTRA_ACTIVITY_REFERRER_PACKAGE, r.host)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Category is supported for API>=26.
r.host?.let { host ->
try {
val category = packageManager.getApplicationInfo(host, 0).category
intent.putExtra(EXTRA_ACTIVITY_REFERRER_CATEGORY, category)
} catch (e: PackageManager.NameNotFoundException) {
// At least we tried.
}
}
}
}
}
private fun Intent.stripUnwantedFlags() {

@ -10,10 +10,10 @@ import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.action.CustomTabListAction
import mozilla.components.browser.state.state.createCustomTab
import mozilla.components.browser.state.state.CustomTabSessionState
import mozilla.components.browser.state.state.EngineState
import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.state.createCustomTab
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.window.WindowRequest
@ -105,7 +105,10 @@ abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, User
protected fun initializeSession(fromEngineSession: EngineSession? = null) {
engineSession = fromEngineSession ?: requireComponents.core.engine.createSession()
session = createCustomTab("").copy(engineState = EngineState(engineSession))
session = createCustomTab(
url = "",
source = SessionState.Source.Internal.CustomTab
).copy(engineState = EngineState(engineSession))
requireComponents.core.store.dispatch(CustomTabListAction.AddCustomTabAction(session as CustomTabSessionState))
}

@ -1006,7 +1006,7 @@ abstract class BaseBrowserFragment :
.collect {
if (!onboarding.userHasBeenOnboarded() &&
it.content.loadRequest?.triggeredByRedirect != true &&
it.source !in intentSourcesList &&
it.source !is SessionState.Source.External &&
it.content.url !in onboardingLinksList
) {
onboarding.finish()
@ -1144,7 +1144,7 @@ abstract class BaseBrowserFragment :
*/
protected open fun removeSessionIfNeeded(): Boolean {
getCurrentTab()?.let { session ->
return if (session.source == SessionState.Source.ACTION_VIEW) {
return if (session.source is SessionState.Source.External && !session.restored) {
activity?.finish()
requireComponents.useCases.tabsUseCases.removeTab(session.id)
true
@ -1396,12 +1396,6 @@ abstract class BaseBrowserFragment :
SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE),
SupportUtils.getFirefoxAccountSumoUrl()
)
val intentSourcesList: List<SessionState.Source> = listOf(
SessionState.Source.ACTION_SEARCH,
SessionState.Source.ACTION_SEND,
SessionState.Source.ACTION_VIEW
)
}
override fun onAccessibilityStateChanged(enabled: Boolean) {

@ -61,14 +61,14 @@ class FennecWebAppIntentProcessor(
val sessionId = if (webAppManifest != null) {
useCases.addWebApp(
url = url,
source = SessionState.Source.HOME_SCREEN,
source = SessionState.Source.Internal.HomeScreen,
webAppManifest = webAppManifest,
customTabConfig = webAppManifest.toCustomTabConfig()
)
} else {
useCases.add(
url = url,
source = SessionState.Source.HOME_SCREEN,
source = SessionState.Source.Internal.HomeScreen,
customTabConfig = createFallbackCustomTabConfig()
)
}

@ -41,7 +41,7 @@ class FennecBookmarkShortcutsIntentProcessor(
val sessionId = addNewTabUseCase(
url = url,
flags = EngineSession.LoadUrlFlags.external(),
source = SessionState.Source.HOME_SCREEN,
source = SessionState.Source.Internal.HomeScreen,
selectTab = true,
startLoading = true
)

@ -261,13 +261,10 @@ class BrowserFragmentTest {
browserFragment.observeTabSource(store)
val newSelectedTab1: TabSessionState = mockk(relaxed = true)
val newSelectedTab2: TabSessionState = mockk(relaxed = true)
val newSelectedTab3: TabSessionState = mockk(relaxed = true)
every { newSelectedTab1.source } returns SessionState.Source.ACTION_SEARCH
every { newSelectedTab2.source } returns SessionState.Source.ACTION_SEND
every { newSelectedTab3.source } returns SessionState.Source.ACTION_VIEW
val newSelectedTab1 = createTab("any-tab-1.org", source = SessionState.Source.External.ActionSearch(mockk()))
val newSelectedTab2 = createTab("any-tab-2.org", source = SessionState.Source.External.ActionView(mockk()))
val newSelectedTab3 = createTab("any-tab-3.org", source = SessionState.Source.External.ActionSend(mockk()))
val newSelectedTab4 = createTab("any-tab-4.org", source = SessionState.Source.External.CustomTab(mockk()))
addAndSelectTab(newSelectedTab1)
verify(exactly = 0) { onboarding.finish() }
@ -277,6 +274,9 @@ class BrowserFragmentTest {
addAndSelectTab(newSelectedTab3)
verify(exactly = 0) { onboarding.finish() }
addAndSelectTab(newSelectedTab4)
verify(exactly = 0) { onboarding.finish() }
}
@Test

@ -53,7 +53,7 @@ class FennecBookmarkShortcutsIntentProcessorTest {
addNewTabUseCase(
url = testUrl,
flags = EngineSession.LoadUrlFlags.external(),
source = SessionState.Source.HOME_SCREEN,
source = SessionState.Source.Internal.HomeScreen,
selectTab = true,
startLoading = true
)
@ -67,7 +67,7 @@ class FennecBookmarkShortcutsIntentProcessorTest {
addNewTabUseCase(
url = testUrl,
flags = EngineSession.LoadUrlFlags.external(),
source = SessionState.Source.HOME_SCREEN,
source = SessionState.Source.Internal.HomeScreen,
selectTab = true,
startLoading = true
)

Loading…
Cancel
Save