diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b3771542f..a4593e02e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -75,14 +75,6 @@ android:taskAffinity="" android:windowSoftInputMode="adjustResize|stateAlwaysHidden" /> - - @@ -185,6 +177,17 @@ android:enabled="${isRaptorEnabled}" android:exported="${isRaptorEnabled}" /> + + + + diff --git a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt index 89a348382..f51053432 100644 --- a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt @@ -13,12 +13,10 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import mozilla.components.feature.intent.processing.TabIntentProcessor import mozilla.components.support.utils.Browsers -import org.mozilla.fenix.customtabs.AuthCustomTabActivity -import org.mozilla.fenix.customtabs.AuthCustomTabActivity.Companion.EXTRA_AUTH_CUSTOM_TAB import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.home.intent.StartSearchIntentProcessor +import org.mozilla.fenix.shortcut.NewTabShortcutIntentProcessor /** * Processes incoming intents and sends them to the corresponding activity. @@ -60,8 +58,9 @@ class IntentReceiverActivity : Activity() { components.intentProcessors.intentProcessor } - val intentProcessors = - components.intentProcessors.externalAppIntentProcessors + tabIntentProcessor + val intentProcessors = components.intentProcessors.externalAppIntentProcessors + + tabIntentProcessor + + NewTabShortcutIntentProcessor() intentProcessors.any { it.process(intent) } setIntentActivity(intent, tabIntentProcessor) @@ -77,13 +76,7 @@ class IntentReceiverActivity : Activity() { private fun setIntentActivity(intent: Intent, tabIntentProcessor: TabIntentProcessor) { val openToBrowser = when { components.intentProcessors.externalAppIntentProcessors.any { it.matches(intent) } -> { - // TODO this needs to change: https://github.com/mozilla-mobile/fenix/issues/5225 - val activityClass = if (intent.hasExtra(EXTRA_AUTH_CUSTOM_TAB)) { - AuthCustomTabActivity::class - } else { - ExternalAppBrowserActivity::class - } - intent.setClassName(applicationContext, activityClass.java.name) + intent.setClassName(applicationContext, ExternalAppBrowserActivity::class.java.name) true } tabIntentProcessor.matches(intent) -> { @@ -94,24 +87,6 @@ class IntentReceiverActivity : Activity() { // from a session that the user already "erased". intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0 } - intent.action == ACTION_OPEN_TAB || intent.action == ACTION_OPEN_PRIVATE_TAB -> { - intent.setClassName(applicationContext, HomeActivity::class.java.name) - val startPrivateMode = (intent.action == ACTION_OPEN_PRIVATE_TAB) - if (startPrivateMode) { - intent.putExtra( - HomeActivity.OPEN_TO_SEARCH, - StartSearchIntentProcessor.STATIC_SHORTCUT_NEW_PRIVATE_TAB - ) - } else { - intent.putExtra( - HomeActivity.OPEN_TO_SEARCH, - StartSearchIntentProcessor.STATIC_SHORTCUT_NEW_TAB - ) - } - intent.putExtra(HomeActivity.PRIVATE_BROWSING_MODE, startPrivateMode) - intent.flags = intent.flags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - false - } else -> { intent.setClassName(applicationContext, HomeActivity::class.java.name) false @@ -124,8 +99,5 @@ class IntentReceiverActivity : Activity() { companion object { // This constant must match the metadata from the private activity-alias const val LAUNCH_PRIVATE_LINK = "org.mozilla.fenix.LAUNCH_PRIVATE_LINK" - - const val ACTION_OPEN_TAB = "org.mozilla.fenix.OPEN_TAB" - const val ACTION_OPEN_PRIVATE_TAB = "org.mozilla.fenix.OPEN_PRIVATE_TAB" } } diff --git a/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt b/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt index 230b12611..e4cac05ca 100644 --- a/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt +++ b/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt @@ -44,6 +44,10 @@ class IntentProcessors( TabIntentProcessor(sessionManager, sessionUseCases.loadUrl, searchUseCases.newTabSearch, isPrivate = true) } + val customTabIntentProcessor by lazy { + CustomTabIntentProcessor(sessionManager, sessionUseCases.loadUrl, context.resources) + } + val externalAppIntentProcessors by lazy { listOf( TrustedWebActivityIntentProcessor( @@ -55,7 +59,7 @@ class IntentProcessors( store = customTabsStore ), WebAppIntentProcessor(sessionManager, sessionUseCases.loadUrl, ManifestStorage(context)), - CustomTabIntentProcessor(sessionManager, sessionUseCases.loadUrl, context.resources) + customTabIntentProcessor ) } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt index 82a83e682..30ae842b4 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt @@ -12,8 +12,8 @@ import mozilla.components.support.ktx.android.content.appVersionName import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.R -import org.mozilla.fenix.customtabs.AuthCustomTabActivity.Companion.EXTRA_AUTH_CUSTOM_TAB import org.mozilla.fenix.ext.getColorFromAttr +import org.mozilla.fenix.settings.account.AuthIntentReceiverActivity import java.io.UnsupportedEncodingException import java.net.URLEncoder import java.util.Locale @@ -68,11 +68,11 @@ object SupportUtils { .build() .intent .setData(url.toUri()) - .setClassName(context.applicationContext, IntentReceiverActivity::class.java.name) + .setClassName(context, IntentReceiverActivity::class.java.name) .setPackage(context.packageName) fun createAuthCustomTabIntent(context: Context, url: String): Intent = - createCustomTabIntent(context, url).putExtra(EXTRA_AUTH_CUSTOM_TAB, true) + createCustomTabIntent(context, url).setClassName(context, AuthIntentReceiverActivity::class.java.name) private fun getEncodedTopicUTF8(topic: String): String { try { diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/AuthCustomTabActivity.kt b/app/src/main/java/org/mozilla/fenix/settings/account/AuthCustomTabActivity.kt similarity index 88% rename from app/src/main/java/org/mozilla/fenix/customtabs/AuthCustomTabActivity.kt rename to app/src/main/java/org/mozilla/fenix/settings/account/AuthCustomTabActivity.kt index cf1e30f56..98b986dc7 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/AuthCustomTabActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/account/AuthCustomTabActivity.kt @@ -2,11 +2,12 @@ * 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 +package org.mozilla.fenix.settings.account import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.OAuthAccount +import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity import org.mozilla.fenix.ext.components /** @@ -28,8 +29,4 @@ class AuthCustomTabActivity : ExternalAppBrowserActivity() { val accountManager = components.backgroundServices.accountManager accountManager.register(accountStateObserver, this, true) } - - companion object { - const val EXTRA_AUTH_CUSTOM_TAB = "support.customtabs.extra.AUTH" - } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/account/AuthIntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/settings/account/AuthIntentReceiverActivity.kt new file mode 100644 index 000000000..427b81d9e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/account/AuthIntentReceiverActivity.kt @@ -0,0 +1,39 @@ +/* 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.settings.account + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import androidx.annotation.VisibleForTesting +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.ext.components + +/** + * Processes incoming intents and sends them to the corresponding activity. + */ +class AuthIntentReceiverActivity : Activity() { + + @VisibleForTesting + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + MainScope().launch { + // The intent property is nullable, but the rest of the code below + // 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() + components.intentProcessors.customTabIntentProcessor.process(intent) + intent.setClassName(applicationContext, AuthCustomTabActivity::class.java.name) + intent.putExtra(HomeActivity.OPEN_TO_BROWSER, true) + + startActivity(intent) + + finish() + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/shortcut/NewTabShortcutIntentProcessor.kt b/app/src/main/java/org/mozilla/fenix/shortcut/NewTabShortcutIntentProcessor.kt new file mode 100644 index 000000000..1c21ae1dc --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/shortcut/NewTabShortcutIntentProcessor.kt @@ -0,0 +1,50 @@ +/* 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.shortcut + +import android.content.Intent +import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK +import mozilla.components.feature.intent.processing.IntentProcessor +import mozilla.components.support.utils.SafeIntent +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.home.intent.StartSearchIntentProcessor + +class NewTabShortcutIntentProcessor : IntentProcessor { + + /** + * Returns true if this intent processor will handle the intent. + */ + override fun matches(intent: Intent): Boolean { + val safeIntent = SafeIntent(intent) + return safeIntent.action == ACTION_OPEN_TAB || safeIntent.action == ACTION_OPEN_PRIVATE_TAB + } + + /** + * Processes the given [Intent]. + * + * @param intent The intent to process. + * @return True if the intent was processed, otherwise false. + */ + override suspend fun process(intent: Intent): Boolean { + val safeIntent = SafeIntent(intent) + val (searchExtra, startPrivateMode) = when (safeIntent.action) { + ACTION_OPEN_TAB -> StartSearchIntentProcessor.STATIC_SHORTCUT_NEW_TAB to false + ACTION_OPEN_PRIVATE_TAB -> StartSearchIntentProcessor.STATIC_SHORTCUT_NEW_PRIVATE_TAB to true + else -> return false + } + + intent.putExtra(HomeActivity.OPEN_TO_SEARCH, searchExtra) + intent.putExtra(HomeActivity.PRIVATE_BROWSING_MODE, startPrivateMode) + intent.flags = intent.flags or FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK + + return true + } + + companion object { + const val ACTION_OPEN_TAB = "org.mozilla.fenix.OPEN_TAB" + const val ACTION_OPEN_PRIVATE_TAB = "org.mozilla.fenix.OPEN_PRIVATE_TAB" + } +}