Dan Ballard pushed to branch tor-browser-153.2.0esr-16.0-1 at The Tor Project / Applications / Tor Browser Commits: 0f6d7a42 by clairehurst at 2026-09-02T17:12:51-06:00 fixup! [android] Implement Android-native Connection Assist UI Bug 45172: Move away from openToBrowserAndLoad() - - - - - 56c0e22d by clairehurst at 2026-09-02T17:13:21-06:00 fixup! [android] Modify UI/UX Bug 45172: Move away from openToBrowserAndLoad() - - - - - 12 changed files: - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/Extensions.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HttpsOnlyFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/about/AboutFragment.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SaveSearchEngineFragment.kt Changes: ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt ===================================== @@ -1475,30 +1475,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, Crash historyMetadata: HistoryMetadataKey? = null, additionalHeaders: Map<String, String>? = null, ) { - if (!components.torController.isBootstrapped && !searchTermOrURL.startsWith("about:")) { - Snackbar.make( - snackBarParentView = binding.root, - snackbarState = SnackbarState( - message = getString(R.string.connection_assist_connect_to_tor_before_opening_links), - duration = SnackbarState.Duration.Preset.Long, - action = Action( - label = getString(R.string.connection_assist_connect_to_tor_before_opening_links_confirmation), - onClick = { - urlQuickLoadViewModel.urlToLoadAfterConnecting.value = searchTermOrURL - urlQuickLoadViewModel.maybeBeginBootstrap() - if (navHost.navController.previousBackStackEntry?.destination?.id == R.id.torConnectionAssistFragment) { - supportFragmentManager.popBackStack() - } else { - navHost.navController.navigate( - TorConnectionAssistFragmentDirections.actionConnectToTorBeforeOpeningLinks(), - ) - } - }, - ), - ), - ).show() - return - } + if (maybeShowConnectToTorPrompt(url = searchTermOrURL)) return openToBrowser(from, customTabSessionId) components.useCases.fenixBrowserUseCases.loadUrlOrSearch( @@ -1813,4 +1790,37 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, Crash e.printStackTrace() } } + + /** + * @return `true` if not connected to tor and the prompt attempted to be shown. + * `false` if connected to tor and prompt does not need to be shown + */ + fun maybeShowConnectToTorPrompt(url: String) : Boolean { + if (!components.torController.isBootstrapped && !url.startsWith("about:")) { + Snackbar.make( + snackBarParentView = binding.root, + snackbarState = SnackbarState( + message = getString(R.string.connection_assist_connect_to_tor_before_opening_links), + duration = SnackbarState.Duration.Preset.Long, + action = Action( + label = getString(R.string.connection_assist_connect_to_tor_before_opening_links_confirmation), + onClick = { + urlQuickLoadViewModel.urlToLoadAfterConnecting.value = url + urlQuickLoadViewModel.maybeBeginBootstrap() + if (navHost.navController.previousBackStackEntry?.destination?.id == R.id.torConnectionAssistFragment) { + supportFragmentManager.popBackStack() + } else { + navHost.navController.navigate( + TorConnectionAssistFragmentDirections.actionConnectToTorBeforeOpeningLinks(), + ) + } + }, + ), + ), + ).show() + return true + } else { + return false + } + } } ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonDetailsFragment.kt ===================================== @@ -19,6 +19,7 @@ import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.ui.showInformationDialog import mozilla.components.feature.addons.ui.translateName import mozilla.components.feature.addons.update.DefaultAddonUpdater.UpdateAttemptStorage +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentAddOnDetailsBinding import org.mozilla.fenix.e2e.SystemInsetsPaddedFragment @@ -51,6 +52,7 @@ class AddonDetailsFragment : } override fun openWebsite(url: Uri) { + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(url.toString())) return findNavController().openToBrowser() requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = url.toString(), ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPermissionsDetailsFragment.kt ===================================== @@ -17,6 +17,7 @@ import androidx.navigation.fragment.navArgs import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.Addon.Companion.isAllURLsPermission import mozilla.components.feature.addons.ui.translateName +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.addons.ui.AddonPermissionsScreen import org.mozilla.fenix.e2e.SystemInsetsPaddedFragment import org.mozilla.fenix.ext.components @@ -171,6 +172,7 @@ class AddonPermissionsDetailsFragment : Fragment(), SystemInsetsPaddedFragment { } private fun openWebsite(addonSiteUrl: String) { + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(addonSiteUrl)) return findNavController().openToBrowser() requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = addonSiteUrl, ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt ===================================== @@ -26,6 +26,7 @@ import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManager import mozilla.components.feature.addons.AddonManagerException import mozilla.components.feature.addons.ui.AddonsManagerAdapter +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentAddOnsManagementBinding import org.mozilla.fenix.e2e.SystemInsetsPaddedFragment @@ -76,6 +77,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), onInstallButtonClicked = ::installAddon, onMoreAddonsButtonClicked = ::openAMO, onLearnMoreClicked = { link, addon -> + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(resolveLearnMoreUrl(link, addon) ?: return@AddonsManagementView)) return@AddonsManagementView binding?.root?.openLearnMoreLink(link, addon) }, ) @@ -204,6 +206,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management), } private fun openAMO() { + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(AMO_HOMEPAGE_FOR_ANDROID)) return findNavController().openToBrowser() requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = AMO_HOMEPAGE_FOR_ANDROID, ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/Extensions.kt ===================================== @@ -48,7 +48,7 @@ internal fun View.openLearnMoreLink( ) } -private fun resolveLearnMoreUrl( +fun resolveLearnMoreUrl( link: AddonsManagerAdapterDelegate.LearnMoreLinks, addon: Addon, ): String? { ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt ===================================== @@ -30,6 +30,7 @@ import mozilla.components.support.ktx.android.content.appName import mozilla.components.support.ktx.android.content.appVersionName import org.mozilla.fenix.BuildConfig import mozilla.components.support.webextensions.WebExtensionSupport.installedExtensions +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.databinding.FragmentInstalledAddOnDetailsBinding import org.mozilla.fenix.e2e.SystemInsetsPaddedFragment import org.mozilla.fenix.ext.components @@ -174,6 +175,7 @@ class InstalledAddonDetailsFragment : Fragment(), SystemInsetsPaddedFragment { messageBarWarningView, messageBarErrorView, onLearnMoreLinkClicked = { link -> + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(resolveLearnMoreUrl(link, addon) ?: return@bindMessageBars)) return@bindMessageBars binding.root.openLearnMoreLink(link, addon) }, addon, ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/menu/MenuDialogFragment.kt ===================================== @@ -1079,6 +1079,7 @@ class MenuDialogFragment : BottomSheetDialogFragment() { } url?.let { + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(url)) return@let findNavController().openToBrowser() requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = url, ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt ===================================== @@ -552,11 +552,13 @@ class HomeFragment : Fragment(), UserInteractionHandler { urlQuickLoadViewModel.urlToLoadAfterConnecting.observe(viewLifecycleOwner) { if (!it.isNullOrBlank()) { - @Suppress("DEPRECATION") - (requireActivity() as HomeActivity).openToBrowserAndLoad( + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(it)) return@observe + (requireActivity() as HomeActivity).openToBrowser( + from = BrowserDirection.FromHome, + ) + requireContext().components.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = it, newTab = true, - from = BrowserDirection.FromHome, ) // Only load this url once urlQuickLoadViewModel.urlToLoadAfterConnecting.value = null ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/HttpsOnlyFragment.kt ===================================== @@ -18,6 +18,7 @@ import androidx.core.view.children import androidx.core.view.isGone import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.databinding.SettingsHttpsOnlyBinding import org.mozilla.fenix.e2e.SystemInsetsPaddedFragment @@ -105,6 +106,7 @@ class HttpsOnlyFragment : Fragment(), SystemInsetsPaddedFragment { val linkClickListener: ClickableSpan = object : ClickableSpan() { override fun onClick(view: View) { view.setOnClickListener { + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(SupportUtils.DONATE_URL)) return@setOnClickListener findNavController().openToBrowser() requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = SupportUtils.getGenericSumoURLForTopic( ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt ===================================== @@ -96,6 +96,7 @@ import mozilla.components.ui.icons.R as iconsR import org.mozilla.fenix.GleanMetrics.Settings as SettingsMetrics import android.view.WindowManager +import org.mozilla.fenix.ext.openToBrowser /** * Main settings screen. @@ -560,15 +561,16 @@ class SettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragment, SettingsFragmentDirections.actionSettingsFragmentToAboutFragment() } - resources.getString(R.string.pref_key_donate) -> { - @Suppress("DEPRECATION") - (activity as HomeActivity).openToBrowserAndLoad( - searchTermOrURL = SupportUtils.DONATE_URL, - newTab = true, - from = BrowserDirection.FromSettings - ) - null - } + resources.getString(R.string.pref_key_donate) -> + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(SupportUtils.DONATE_URL)) null + else { + findNavController().openToBrowser() + requireContext().components.useCases.fenixBrowserUseCases.loadUrlOrSearch( + searchTermOrURL = SupportUtils.DONATE_URL, + newTab = true, + ) + null + } // Only displayed when secret settings are enabled resources.getString(R.string.pref_key_debug_settings) -> { @@ -825,12 +827,9 @@ class SettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragment, requirePreference<Preference>(R.string.pref_key_about_config_shortcut).apply { isVisible = requireContext().components.settings.showSecretDebugMenuThisSession || Config.channel == ReleaseChannel.Debug setOnPreferenceClickListener { - @Suppress("DEPRECATION") - (requireActivity() as HomeActivity).openToBrowserAndLoad( - searchTermOrURL = "about:config", - from = BrowserDirection.FromSettings, - newTab = true, - ) + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt("about:config")) return@setOnPreferenceClickListener true + findNavController().openToBrowser() + components.useCases.fenixBrowserUseCases.loadUrlOrSearch("about:config", newTab = true) true } } ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/about/AboutFragment.kt ===================================== @@ -38,6 +38,8 @@ import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.whatsnew.WhatsNew import org.mozilla.geckoview.BuildConfig as GeckoViewBuildConfig +import org.mozilla.fenix.HomeActivity + /** * Displays the logo and information about the app, including library versions. */ @@ -244,6 +246,7 @@ class AboutFragment( } private fun openLinkInNormalTab(url: String) { + if ((requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(url)) return findNavController().openToBrowser() requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( searchTermOrURL = url, ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/search/SaveSearchEngineFragment.kt ===================================== @@ -17,6 +17,7 @@ import kotlinx.coroutines.launch import mozilla.components.browser.icons.IconRequest import mozilla.components.feature.search.ext.createSearchEngine import org.mozilla.fenix.GleanMetrics.Events +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.databinding.FragmentSaveSearchEngineBinding import org.mozilla.fenix.e2e.SystemInsetsPaddedFragment @@ -85,14 +86,17 @@ class SaveSearchEngineFragment : Fragment(R.layout.fragment_save_search_engine), } val learnMoreListener: (View) -> Unit = { - findNavController().openToBrowser() - requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( - searchTermOrURL = SupportUtils.getSumoURLForTopic( - requireContext(), - SupportUtils.SumoTopic.CUSTOM_SEARCH_ENGINES, - ), - newTab = true, + val url = SupportUtils.getSumoURLForTopic( + requireContext(), + SupportUtils.SumoTopic.CUSTOM_SEARCH_ENGINES, ) + if (!(requireActivity() as HomeActivity).maybeShowConnectToTorPrompt(url)) { + findNavController().openToBrowser() + requireComponents.useCases.fenixBrowserUseCases.loadUrlOrSearch( + searchTermOrURL = url, + newTab = true, + ) + } } binding.customSearchEnginesLearnMoreWrapper.setOnClickListener(learnMoreListener) binding.customSearchSuggestionsLearnMoreWrapper.setOnClickListener(learnMoreListener) View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/f111c7e... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/f111c7e... You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
participants (1)
-
Dan Ballard (@dan)