tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 37dc7a3ae7049fb7ab5a1f78c9badcefc13d53ad
parent 975e3fec8d22f809bdbf74e43221676f457c9978
Author: Andrew Creskey <acreskey@mozilla.com>
Date:   Thu,  2 Oct 2025 16:03:03 +0000

Bug 1956356 Fenix - create a speculative connection to the applink host r=kaya,android-reviewers,jonalmeida

Create a speculative connection to the applink host upon receipt of the view intent.
This will allow the connection to be established earlier, generally by the time we need to load the url.

Differential Revision: https://phabricator.services.mozilla.com/D243446

Diffstat:
Mmobile/android/android-components/components/feature/intent/src/main/java/mozilla/components/feature/intent/processing/TabIntentProcessor.kt | 28++++++++++++++++++++++++++--
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt | 4++--
2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/mobile/android/android-components/components/feature/intent/src/main/java/mozilla/components/feature/intent/processing/TabIntentProcessor.kt b/mobile/android/android-components/components/feature/intent/src/main/java/mozilla/components/feature/intent/processing/TabIntentProcessor.kt @@ -20,6 +20,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.externalPackage +import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.EngineSession.LoadUrlFlags import mozilla.components.concept.engine.EngineSession.LoadUrlFlags.Companion.APP_LINK_LAUNCH_TYPE_UNKNOWN import mozilla.components.feature.search.SearchUseCases @@ -46,6 +47,7 @@ class TabIntentProcessor( private val tabsUseCases: TabsUseCases, private val newTabSearchUseCase: SearchUseCases.NewTabSearchUseCase, private val isPrivate: Boolean = false, + private val engine: Engine? = null, ) : IntentProcessor { private val logger = Logger("TabIntentProcessor") @@ -60,7 +62,8 @@ class TabIntentProcessor( false } else { // Don't do app-link DNS warmup when DoH is enabled. See Bug 1929005. - warmupDNS(url.toNormalizedUrl()) + warmupNativeDNS(url.toNormalizedUrl()) + createSpeculativeConnection(url.toNormalizedUrl()) val flags = computeLoadUrlFlags(intent) @@ -87,7 +90,7 @@ class TabIntentProcessor( } @OptIn(DelicateCoroutinesApi::class) // GlobalScope usage for DNS warmup in the background - private fun warmupDNS(normalizedUrl: String) { + private fun warmupNativeDNS(normalizedUrl: String) { GlobalScope.launch(IO) { try { val url = URL(normalizedUrl) @@ -100,6 +103,25 @@ class TabIntentProcessor( } } + /** + * Creates a speculative connection to the given URL using the engine. + */ + private fun createSpeculativeConnection(normalizedUrl: String) { + engine?.let { engineInstance -> + try { + engineInstance.speculativeConnect(normalizedUrl) + } catch (e: MalformedURLException) { + logger.error("Failed to create speculative connection: Invalid URL format - ${e.message}") + } catch (e: UnknownHostException) { + logger.error("Failed to create speculative connection: Unknown host - ${e.message}") + } catch (e: SecurityException) { + logger.error("Failed to create speculative connection: Security violation - ${e.message}") + } catch (e: IllegalStateException) { + logger.error("Failed to create speculative connection: Engine in invalid state - ${e.message}") + } + } + } + /** * Processes a send intent and tries to load [EXTRA_TEXT] as a URL. * If it's not a URL, a search is run instead. @@ -138,6 +160,8 @@ class TabIntentProcessor( } private fun addNewTab(url: String, source: SessionState.Source) { + createSpeculativeConnection(url.toNormalizedUrl()) + tabsUseCases.addTab( url.toNormalizedUrl(), source = source, diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/IntentProcessors.kt @@ -45,14 +45,14 @@ class IntentProcessors( * Provides intent processing functionality for ACTION_VIEW and ACTION_SEND intents. */ val intentProcessor by lazyMonitored { - TabIntentProcessor(tabsUseCases, searchUseCases.newTabSearch, isPrivate = false) + TabIntentProcessor(tabsUseCases, searchUseCases.newTabSearch, isPrivate = false, engine = engine) } /** * Provides intent processing functionality for ACTION_VIEW and ACTION_SEND intents in private tabs. */ val privateIntentProcessor by lazyMonitored { - TabIntentProcessor(tabsUseCases, searchUseCases.newPrivateTabSearch, isPrivate = true) + TabIntentProcessor(tabsUseCases, searchUseCases.newPrivateTabSearch, isPrivate = true, engine = engine) } val customTabIntentProcessor by lazyMonitored {