From a477f14042150af806dd4a766571cbc0161f3020 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Thu, 27 Feb 2020 16:02:55 +0100 Subject: [PATCH] IntentReceiverActivity: Simplify intent handling. This patch removes the need to process() and then match() on every intent processor. A successful process() means that we already matched. Doing this in two steps caused issues when the process() failed but later the simple check in match() returned true. After this patch lands I intent to remove the match() API from the IntentProcessor interface in AC: https://github.com/mozilla-mobile/android-components/issues/6097 --- .../mozilla/fenix/IntentReceiverActivity.kt | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt index 183f8c2ef..61731e2f4 100644 --- a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt @@ -10,6 +10,8 @@ import android.os.Bundle import androidx.annotation.VisibleForTesting import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch +import mozilla.components.feature.intent.processing.IntentProcessor +import org.mozilla.fenix.components.IntentProcessorType import org.mozilla.fenix.components.getType import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components @@ -30,14 +32,29 @@ class IntentReceiverActivity : Activity() { // assumes it is not. If it's null, then we make a new one and open // the HomeActivity. val intent = intent?.let { Intent(intent) } ?: Intent() + intent.stripUnwantedFlags() processIntent(intent) } } suspend fun processIntent(intent: Intent) { - val settings = settings() + // Call process for side effects, short on the first that returns true + val processor = getIntentProcessors().firstOrNull { it.process(intent) } + val intentProcessorType = components.intentProcessors.getType(processor) + + launch(intent, intentProcessorType) + } + + private fun launch(intent: Intent, intentProcessorType: IntentProcessorType) { + intent.setClassName(applicationContext, intentProcessorType.activityClassName) + intent.putExtra(HomeActivity.OPEN_TO_BROWSER, intentProcessorType.shouldOpenToBrowser(intent)) - val modeDependentProcessors = if (settings.openLinksInAPrivateTab) { + startActivity(intent) + finish() // must finish() after starting the other activity + } + + private fun getIntentProcessors(): List { + val modeDependentProcessors = if (settings().openLinksInAPrivateTab) { components.analytics.metrics.track(Event.OpenedLink(Event.OpenedLink.Mode.PRIVATE)) intent.putExtra(HomeActivity.PRIVATE_BROWSING_MODE, true) listOf( @@ -53,31 +70,20 @@ class IntentReceiverActivity : Activity() { ) } - val intentProcessors = listOf(components.intentProcessors.migrationIntentProcessor) + - components.intentProcessors.externalAppIntentProcessors + - modeDependentProcessors + - NewTabShortcutIntentProcessor() - - // Explicitly remove the new task and clear task flags (Our browser activity is a single - // task activity and we never want to start a second task here). - intent.flags = intent.flags and Intent.FLAG_ACTIVITY_NEW_TASK.inv() - intent.flags = intent.flags and Intent.FLAG_ACTIVITY_CLEAR_TASK.inv() - - // IntentReceiverActivity is started with the "excludeFromRecents" flag (set in manifest). We - // do not want to propagate this flag from the intent receiver activity to the browser. - intent.flags = intent.flags and Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.inv() - - // Call process for side effects, short on the first that returns true - intentProcessors.any { it.process(intent) } - - val intentProcessorType = - components.intentProcessors.getType(intentProcessors.firstOrNull { it.matches(intent) }) + return listOf(components.intentProcessors.migrationIntentProcessor) + + components.intentProcessors.externalAppIntentProcessors + + modeDependentProcessors + + NewTabShortcutIntentProcessor() + } +} - intent.setClassName(applicationContext, intentProcessorType.activityClassName) - intent.putExtra(HomeActivity.OPEN_TO_BROWSER, intentProcessorType.shouldOpenToBrowser(intent)) +private fun Intent.stripUnwantedFlags() { + // Explicitly remove the new task and clear task flags (Our browser activity is a single + // task activity and we never want to start a second task here). + flags = flags and Intent.FLAG_ACTIVITY_NEW_TASK.inv() + flags = flags and Intent.FLAG_ACTIVITY_CLEAR_TASK.inv() - startActivity(intent) - // must finish() after starting the other activity - finish() - } + // IntentReceiverActivity is started with the "excludeFromRecents" flag (set in manifest). We + // do not want to propagate this flag from the intent receiver activity to the browser. + flags = flags and Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.inv() }