morgan pushed to branch tor-browser-128.5.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
938f751c
by clairehurst at 2024-12-04T11:50:34-07:00
9 changed files:
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.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/SettingsFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerGV.kt
- mobile/android/fenix/app/src/main/res/layout/fenix_snackbar.xml
- mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml
- mobile/android/fenix/app/src/main/res/values/torbrowser_strings.xml
Changes:
| ... | ... | @@ -25,6 +25,7 @@ import android.view.MotionEvent |
| 25 | 25 | import android.view.View
|
| 26 | 26 | import android.view.ViewConfiguration
|
| 27 | 27 | import android.view.WindowManager.LayoutParams.FLAG_SECURE
|
| 28 | +import androidx.activity.viewModels
|
|
| 28 | 29 | import androidx.annotation.CallSuper
|
| 29 | 30 | import androidx.annotation.IdRes
|
| 30 | 31 | import androidx.annotation.RequiresApi
|
| ... | ... | @@ -32,7 +33,6 @@ import androidx.annotation.VisibleForTesting |
| 32 | 33 | import androidx.appcompat.app.ActionBar
|
| 33 | 34 | import androidx.appcompat.widget.Toolbar
|
| 34 | 35 | import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
| 35 | -import androidx.core.content.ContentProviderCompat.requireContext
|
|
| 36 | 36 | import androidx.lifecycle.lifecycleScope
|
| 37 | 37 | import androidx.navigation.NavController
|
| 38 | 38 | import androidx.navigation.fragment.NavHostFragment
|
| ... | ... | @@ -151,10 +151,10 @@ import org.mozilla.fenix.utils.Settings |
| 151 | 151 | import java.lang.ref.WeakReference
|
| 152 | 152 | import java.util.Locale
|
| 153 | 153 | |
| 154 | -import androidx.navigation.fragment.findNavController
|
|
| 155 | 154 | import mozilla.components.browser.engine.gecko.GeckoEngine
|
| 156 | -import mozilla.components.browser.state.selector.findCustomTab
|
|
| 155 | +import org.mozilla.fenix.components.FenixSnackbar
|
|
| 157 | 156 | import org.mozilla.fenix.home.HomeFragment
|
| 157 | +import org.mozilla.fenix.tor.TorConnectionAssistViewModel
|
|
| 158 | 158 | import org.mozilla.geckoview.TorIntegrationAndroid
|
| 159 | 159 | |
| 160 | 160 | /**
|
| ... | ... | @@ -238,6 +238,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn |
| 238 | 238 | |
| 239 | 239 | private var dialog: RedirectDialogFragment? = null
|
| 240 | 240 | |
| 241 | + private val torConnectionAssistViewModel: TorConnectionAssistViewModel by viewModels()
|
|
| 242 | + |
|
| 241 | 243 | @Suppress("ComplexMethod")
|
| 242 | 244 | final override fun onCreate(savedInstanceState: Bundle?) {
|
| 243 | 245 | // DO NOT MOVE ANYTHING ABOVE THIS getProfilerTime CALL.
|
| ... | ... | @@ -1115,6 +1117,25 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn |
| 1115 | 1117 | historyMetadata: HistoryMetadataKey? = null,
|
| 1116 | 1118 | additionalHeaders: Map<String, String>? = null,
|
| 1117 | 1119 | ) {
|
| 1120 | + if (!components.torController.isBootstrapped && !searchTermOrURL.startsWith("about:")) {
|
|
| 1121 | + FenixSnackbar.make(
|
|
| 1122 | + view = binding.root,
|
|
| 1123 | + isDisplayedWithBrowserToolbar = true,
|
|
| 1124 | + )
|
|
| 1125 | + .setText(getString(R.string.connection_assist_connect_to_tor_before_opening_links))
|
|
| 1126 | + .setAction(getString(R.string.connection_assist_connect_to_tor_before_opening_links_confirmation)) {
|
|
| 1127 | + torConnectionAssistViewModel.handleConnect(searchTermOrURL)
|
|
| 1128 | + if (navHost.navController.previousBackStackEntry?.destination?.id == R.id.torConnectionAssistFragment) {
|
|
| 1129 | + supportFragmentManager.popBackStack()
|
|
| 1130 | + } else {
|
|
| 1131 | + navHost.navController.navigate(
|
|
| 1132 | + TorConnectionAssistFragmentDirections.actionConnectToTorBeforeOpeningLinks()
|
|
| 1133 | + )
|
|
| 1134 | + }
|
|
| 1135 | + }
|
|
| 1136 | + .show()
|
|
| 1137 | + return
|
|
| 1138 | + }
|
|
| 1118 | 1139 | openToBrowser(from, customTabSessionId)
|
| 1119 | 1140 | load(
|
| 1120 | 1141 | searchTermOrURL = searchTermOrURL,
|
| ... | ... | @@ -1434,8 +1455,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn |
| 1434 | 1455 | override fun onBootstrapStateChange(state: String) = Unit
|
| 1435 | 1456 | override fun onBootstrapProgress(progress: Double, hasWarnings: Boolean) = Unit
|
| 1436 | 1457 | override fun onBootstrapComplete() {
|
| 1437 | - components.useCases.tabsUseCases.removeAllTabs()
|
|
| 1438 | - navHost.navController.navigate(NavGraphDirections.actionStartupHome())
|
|
| 1458 | + if (settings().useHtmlConnectionUi) {
|
|
| 1459 | + components.useCases.tabsUseCases.removeAllTabs()
|
|
| 1460 | + navHost.navController.navigate(NavGraphDirections.actionStartupHome())
|
|
| 1461 | + }
|
|
| 1439 | 1462 | }
|
| 1440 | 1463 | override fun onBootstrapError(code: String?, message: String?, phase: String?, reason: String?) = Unit
|
| 1441 | 1464 | } |
| ... | ... | @@ -160,6 +160,7 @@ import org.mozilla.fenix.tabstray.TabsTrayAccessPoint |
| 160 | 160 | import org.mozilla.fenix.theme.FirefoxTheme
|
| 161 | 161 | import org.mozilla.fenix.tor.TorBootstrapFragmentDirections
|
| 162 | 162 | import org.mozilla.fenix.tor.TorBootstrapStatus
|
| 163 | +import org.mozilla.fenix.tor.TorConnectionAssistViewModel
|
|
| 163 | 164 | import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
|
| 164 | 165 | import org.mozilla.fenix.utils.allowUndo
|
| 165 | 166 | import org.mozilla.fenix.wallpapers.Wallpaper
|
| ... | ... | @@ -179,6 +180,7 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
| 179 | 180 | private val binding get() = _binding!!
|
| 180 | 181 | |
| 181 | 182 | private val homeViewModel: HomeScreenViewModel by activityViewModels()
|
| 183 | + private val torConnectionAssistViewModel: TorConnectionAssistViewModel by activityViewModels()
|
|
| 182 | 184 | |
| 183 | 185 | private val snackbarAnchorView: View?
|
| 184 | 186 | get() = when (requireContext().settings().toolbarPosition) {
|
| ... | ... | @@ -899,6 +901,17 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
| 899 | 901 | view = view,
|
| 900 | 902 | )
|
| 901 | 903 | |
| 904 | + torConnectionAssistViewModel.urlToLoadAfterConnecting.also {
|
|
| 905 | + if(!it.isNullOrBlank()){
|
|
| 906 | + (requireActivity() as HomeActivity).openToBrowserAndLoad(
|
|
| 907 | + searchTermOrURL = it,
|
|
| 908 | + newTab = true,
|
|
| 909 | + from = BrowserDirection.FromHome,
|
|
| 910 | + )
|
|
| 911 | + torConnectionAssistViewModel.urlToLoadAfterConnecting = null // Only load this url once
|
|
| 912 | + }
|
|
| 913 | + }
|
|
| 914 | + |
|
| 902 | 915 | // DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
|
| 903 | 916 | requireComponents.core.engine.profiler?.addMarker(
|
| 904 | 917 | MarkersFragmentLifecycleCallbacks.MARKER_NAME,
|
| ... | ... | @@ -25,6 +25,7 @@ import androidx.lifecycle.Observer |
| 25 | 25 | import androidx.lifecycle.lifecycleScope
|
| 26 | 26 | import androidx.navigation.NavDirections
|
| 27 | 27 | import androidx.navigation.findNavController
|
| 28 | +import androidx.navigation.fragment.findNavController
|
|
| 28 | 29 | import androidx.navigation.fragment.navArgs
|
| 29 | 30 | import androidx.preference.Preference
|
| 30 | 31 | import androidx.preference.PreferenceFragmentCompat
|
| ... | ... | @@ -40,6 +41,7 @@ import mozilla.components.concept.sync.OAuthAccount |
| 40 | 41 | import mozilla.components.concept.sync.Profile
|
| 41 | 42 | import mozilla.components.feature.addons.ui.AddonFilePicker
|
| 42 | 43 | import mozilla.components.service.glean.private.NoExtras
|
| 44 | +import mozilla.components.support.base.feature.UserInteractionHandler
|
|
| 43 | 45 | import mozilla.components.support.ktx.android.view.showKeyboard
|
| 44 | 46 | import mozilla.components.ui.widgets.withCenterAlignedButtons
|
| 45 | 47 | import org.mozilla.fenix.BrowserDirection
|
| ... | ... | @@ -77,7 +79,7 @@ import kotlin.system.exitProcess |
| 77 | 79 | import org.mozilla.fenix.GleanMetrics.Settings as SettingsMetrics
|
| 78 | 80 | |
| 79 | 81 | @Suppress("LargeClass", "TooManyFunctions")
|
| 80 | -class SettingsFragment : PreferenceFragmentCompat() {
|
|
| 82 | +class SettingsFragment : PreferenceFragmentCompat(), UserInteractionHandler {
|
|
| 81 | 83 | |
| 82 | 84 | private val args by navArgs<SettingsFragmentArgs>()
|
| 83 | 85 | private lateinit var accountUiView: AccountUiView
|
| ... | ... | @@ -883,4 +885,18 @@ class SettingsFragment : PreferenceFragmentCompat() { |
| 883 | 885 | private const val FXA_SYNC_OVERRIDE_EXIT_DELAY = 2000L
|
| 884 | 886 | private const val AMO_COLLECTION_OVERRIDE_EXIT_DELAY = 3000L
|
| 885 | 887 | }
|
| 888 | + |
|
| 889 | + override fun onBackPressed(): Boolean {
|
|
| 890 | + // If tor is already bootstrapped, skip going back to [TorConnectionAssistFragment] and instead go directly to [HomeFragment]
|
|
| 891 | + if (requireComponents.torController.isBootstrapped) {
|
|
| 892 | + val navController = findNavController()
|
|
| 893 | + if (navController.previousBackStackEntry?.destination?.id == R.id.torConnectionAssistFragment) {
|
|
| 894 | + navController.navigate(
|
|
| 895 | + SettingsFragmentDirections.actionGlobalHomeFragment(),
|
|
| 896 | + )
|
|
| 897 | + return true
|
|
| 898 | + }
|
|
| 899 | + }
|
|
| 900 | + return false
|
|
| 901 | + }
|
|
| 886 | 902 | } |
| ... | ... | @@ -19,7 +19,7 @@ import android.view.View |
| 19 | 19 | import android.view.ViewGroup
|
| 20 | 20 | import androidx.appcompat.content.res.AppCompatResources
|
| 21 | 21 | import androidx.fragment.app.Fragment
|
| 22 | -import androidx.fragment.app.viewModels
|
|
| 22 | +import androidx.fragment.app.activityViewModels
|
|
| 23 | 23 | import androidx.lifecycle.Lifecycle
|
| 24 | 24 | import androidx.lifecycle.lifecycleScope
|
| 25 | 25 | import androidx.lifecycle.repeatOnLifecycle
|
| ... | ... | @@ -34,7 +34,7 @@ import org.mozilla.fenix.ext.hideToolbar |
| 34 | 34 | class TorConnectionAssistFragment : Fragment(), UserInteractionHandler {
|
| 35 | 35 | |
| 36 | 36 | private val TAG = "TorConnectionAssistFrag"
|
| 37 | - private val viewModel: TorConnectionAssistViewModel by viewModels()
|
|
| 37 | + private val viewModel: TorConnectionAssistViewModel by activityViewModels()
|
|
| 38 | 38 | private var _binding: FragmentTorConnectionAssistBinding? = null
|
| 39 | 39 | private val binding get() = _binding!!
|
| 40 | 40 | |
| ... | ... | @@ -46,6 +46,11 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 46 | 46 | _binding = FragmentTorConnectionAssistBinding.inflate(
|
| 47 | 47 | inflater, container, false,
|
| 48 | 48 | )
|
| 49 | + viewLifecycleOwner.lifecycleScope.launch {
|
|
| 50 | + repeatOnLifecycle(Lifecycle.State.STARTED) {
|
|
| 51 | + viewModel.collectLastKnownStatus()
|
|
| 52 | + }
|
|
| 53 | + }
|
|
| 49 | 54 | |
| 50 | 55 | viewLifecycleOwner.lifecycleScope.launch {
|
| 51 | 56 | repeatOnLifecycle(Lifecycle.State.STARTED) {
|
| ... | ... | @@ -62,7 +67,6 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 62 | 67 | override fun onResume() {
|
| 63 | 68 | super.onResume()
|
| 64 | 69 | hideToolbar()
|
| 65 | - viewModel.handleTorConnectStateToScreen() // Covers the case where the app is backgrounded when the bootstrap finishes
|
|
| 66 | 70 | }
|
| 67 | 71 | |
| 68 | 72 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
| ... | ... | @@ -71,11 +75,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 71 | 75 | viewModel.progress().observe(
|
| 72 | 76 | viewLifecycleOwner,
|
| 73 | 77 | ) { progress ->
|
| 74 | - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
| 75 | - binding.torBootstrapProgressBar.setProgress(progress, true)
|
|
| 76 | - } else {
|
|
| 77 | - binding.torBootstrapProgressBar.progress = progress
|
|
| 78 | - }
|
|
| 78 | + setProgressBarCompat(progress)
|
|
| 79 | 79 | }
|
| 80 | 80 | |
| 81 | 81 | viewModel.quickstartToggle().observe(
|
| ... | ... | @@ -95,6 +95,14 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 95 | 95 | |
| 96 | 96 | }
|
| 97 | 97 | |
| 98 | + private fun setProgressBarCompat(progress: Int) {
|
|
| 99 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
| 100 | + binding.torBootstrapProgressBar.setProgress(progress, true)
|
|
| 101 | + } else {
|
|
| 102 | + binding.torBootstrapProgressBar.progress = progress
|
|
| 103 | + }
|
|
| 104 | + }
|
|
| 105 | + |
|
| 98 | 106 | private fun showScreen(screen: ConnectAssistUiState) {
|
| 99 | 107 | setProgressBar(screen)
|
| 100 | 108 | setSettingsButton(screen)
|
| ... | ... | @@ -269,7 +277,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 269 | 277 | |
| 270 | 278 | private fun openHome() {
|
| 271 | 279 | Log.d(TAG, "openHome()")
|
| 272 | - findNavController().navigate(TorConnectionAssistFragmentDirections.actionStartupHome())
|
|
| 280 | + viewModel.openHome(findNavController())
|
|
| 273 | 281 | }
|
| 274 | 282 | |
| 275 | 283 | private fun openSettings(preferenceToScrollTo: String? = null) {
|
| ... | ... | @@ -10,6 +10,7 @@ import androidx.lifecycle.AndroidViewModel |
| 10 | 10 | import androidx.lifecycle.LifecycleCoroutineScope
|
| 11 | 11 | import androidx.lifecycle.LiveData
|
| 12 | 12 | import androidx.lifecycle.MutableLiveData
|
| 13 | +import androidx.navigation.NavController
|
|
| 13 | 14 | import kotlinx.coroutines.flow.MutableStateFlow
|
| 14 | 15 | import kotlinx.coroutines.flow.StateFlow
|
| 15 | 16 | import org.mozilla.fenix.ext.components
|
| ... | ... | @@ -44,20 +45,25 @@ class TorConnectionAssistViewModel( |
| 44 | 45 | }
|
| 45 | 46 | |
| 46 | 47 | init {
|
| 47 | - Log.d(TAG, "initiating TorConnectionAssistViewModel")
|
|
| 48 | + Log.d(TAG, "initiating TorConnectionAssistViewModel $this")
|
|
| 48 | 49 | _torController.registerTorListener(this)
|
| 49 | - handleTorConnectStateToScreen() // should cover the case of when we have an onBootStrapStateChange() event before this is initialized, which lead to being stuck on the splash screen
|
|
| 50 | 50 | }
|
| 51 | 51 | |
| 52 | - private fun handleConnect(
|
|
| 52 | + var urlToLoadAfterConnecting: String? = null
|
|
| 53 | + |
|
| 54 | + fun handleConnect(
|
|
| 55 | + urlToLoadAfterConnecting: String? = null,
|
|
| 53 | 56 | withDebugLogging: Boolean = false,
|
| 54 | 57 | lifecycleScope: LifecycleCoroutineScope? = null,
|
| 55 | 58 | ) {
|
| 56 | - Log.d(TAG, "handleConnect initiatingTorBootstrap with lifecycleScope = $lifecycleScope")
|
|
| 57 | - _torController.initiateTorBootstrap(
|
|
| 58 | - withDebugLogging = withDebugLogging,
|
|
| 59 | - lifecycleScope = lifecycleScope,
|
|
| 60 | - )
|
|
| 59 | + this.urlToLoadAfterConnecting = urlToLoadAfterConnecting
|
|
| 60 | + if (_torController.lastKnownStatus.value.isOff()) {
|
|
| 61 | + Log.d(TAG, "handleConnect() triggered, initiatingTorBootstrap")
|
|
| 62 | + _torController.initiateTorBootstrap(
|
|
| 63 | + withDebugLogging = withDebugLogging,
|
|
| 64 | + lifecycleScope = lifecycleScope,
|
|
| 65 | + )
|
|
| 66 | + }
|
|
| 61 | 67 | }
|
| 62 | 68 | |
| 63 | 69 | fun handleQuickstartChecked(checked: Boolean) {
|
| ... | ... | @@ -96,18 +102,19 @@ class TorConnectionAssistViewModel( |
| 96 | 102 | _progress.value = progress.toInt()
|
| 97 | 103 | }
|
| 98 | 104 | |
| 99 | - handleTorConnectStateToScreen()
|
|
| 100 | 105 | }
|
| 101 | 106 | |
| 102 | - fun handleTorConnectStateToScreen() {
|
|
| 103 | - when (_torController.lastKnownStatus) {
|
|
| 104 | - TorConnectState.Initial -> _torConnectScreen.value = ConnectAssistUiState.Splash
|
|
| 105 | - TorConnectState.Configuring -> handleConfiguring()
|
|
| 106 | - TorConnectState.AutoBootstrapping -> handleBootstrap()
|
|
| 107 | - TorConnectState.Bootstrapping -> handleBootstrap()
|
|
| 108 | - TorConnectState.Bootstrapped -> _shouldOpenHome.value = true
|
|
| 109 | - TorConnectState.Disabled -> _shouldOpenHome.value = true
|
|
| 110 | - TorConnectState.Error -> handleError()
|
|
| 107 | + suspend fun collectLastKnownStatus() {
|
|
| 108 | + _torController.lastKnownStatus.collect {
|
|
| 109 | + when (it) {
|
|
| 110 | + TorConnectState.Initial -> _torConnectScreen.value = ConnectAssistUiState.Splash
|
|
| 111 | + TorConnectState.Configuring -> handleConfiguring()
|
|
| 112 | + TorConnectState.AutoBootstrapping -> handleBootstrap()
|
|
| 113 | + TorConnectState.Bootstrapping -> handleBootstrap()
|
|
| 114 | + TorConnectState.Bootstrapped -> _shouldOpenHome.value = true
|
|
| 115 | + TorConnectState.Disabled -> _shouldOpenHome.value = true
|
|
| 116 | + TorConnectState.Error -> handleError()
|
|
| 117 | + }
|
|
| 111 | 118 | }
|
| 112 | 119 | }
|
| 113 | 120 | |
| ... | ... | @@ -254,4 +261,10 @@ class TorConnectionAssistViewModel( |
| 254 | 261 | }
|
| 255 | 262 | return true
|
| 256 | 263 | }
|
| 264 | + |
|
| 265 | + fun openHome(navController: NavController) {
|
|
| 266 | + navController.navigate(
|
|
| 267 | + TorConnectionAssistFragmentDirections.actionHome(),
|
|
| 268 | + )
|
|
| 269 | + }
|
|
| 257 | 270 | } |
| ... | ... | @@ -4,6 +4,8 @@ package org.mozilla.fenix.tor |
| 4 | 4 | import android.content.Context
|
| 5 | 5 | import android.util.Log
|
| 6 | 6 | import androidx.lifecycle.LifecycleCoroutineScope
|
| 7 | +import kotlinx.coroutines.flow.MutableStateFlow
|
|
| 8 | +import kotlinx.coroutines.flow.StateFlow
|
|
| 7 | 9 | import mozilla.components.browser.engine.gecko.GeckoEngine
|
| 8 | 10 | import org.mozilla.fenix.ext.components
|
| 9 | 11 | import org.mozilla.geckoview.TorIntegrationAndroid
|
| ... | ... | @@ -54,20 +56,22 @@ class TorControllerGV( |
| 54 | 56 | private var torListeners = mutableListOf<TorEvents>()
|
| 55 | 57 | private var torLogListeners = mutableListOf<TorLogs>()
|
| 56 | 58 | |
| 57 | - internal var lastKnownStatus = TorConnectState.Initial
|
|
| 59 | + private val _lastKnownStatus = MutableStateFlow(TorConnectState.Initial)
|
|
| 60 | + internal val lastKnownStatus: StateFlow<TorConnectState> = _lastKnownStatus
|
|
| 61 | + |
|
| 58 | 62 | internal var lastKnownError: TorError? = null
|
| 59 | 63 | private var wasTorBootstrapped = false
|
| 60 | 64 | private var isTorRestarting = false
|
| 61 | 65 | |
| 62 | 66 | private var isTorBootstrapped = false
|
| 63 | - get() = ((lastKnownStatus.isStarted()) && wasTorBootstrapped)
|
|
| 67 | + get() = ((_lastKnownStatus.value.isStarted()) && wasTorBootstrapped)
|
|
| 64 | 68 | |
| 65 | 69 | private val entries = mutableListOf<Pair<String?, String?>>()
|
| 66 | 70 | override val logEntries get() = entries
|
| 67 | - override val isStarting get() = lastKnownStatus.isStarting()
|
|
| 71 | + override val isStarting get() = _lastKnownStatus.value.isStarting()
|
|
| 68 | 72 | override val isRestarting get() = isTorRestarting
|
| 69 | 73 | override val isBootstrapped get() = isTorBootstrapped
|
| 70 | - override val isConnected get() = (lastKnownStatus.isStarted() && !isTorRestarting)
|
|
| 74 | + override val isConnected get() = (_lastKnownStatus.value.isStarted() && !isTorRestarting)
|
|
| 71 | 75 | |
| 72 | 76 | override var quickstart: Boolean
|
| 73 | 77 | get() {
|
| ... | ... | @@ -267,13 +271,13 @@ class TorControllerGV( |
| 267 | 271 | }
|
| 268 | 272 | |
| 269 | 273 | override fun setTorStopped() {
|
| 270 | - lastKnownStatus = TorConnectState.Configuring
|
|
| 274 | + _lastKnownStatus.value = TorConnectState.Configuring
|
|
| 271 | 275 | onTorStatusUpdate(null, lastKnownStatus.toString(), 0.0)
|
| 272 | 276 | onTorStopped()
|
| 273 | 277 | }
|
| 274 | 278 | |
| 275 | 279 | override fun restartTor() {
|
| 276 | - if (!lastKnownStatus.isStarted() && wasTorBootstrapped) {
|
|
| 280 | + if (!_lastKnownStatus.value.isStarted() && wasTorBootstrapped) {
|
|
| 277 | 281 | // If we aren't started, but we were previously bootstrapped,
|
| 278 | 282 | // then we handle a "restart" request as a "start" restart
|
| 279 | 283 | initiateTorBootstrap()
|
| ... | ... | @@ -321,42 +325,22 @@ class TorControllerGV( |
| 321 | 325 | }
|
| 322 | 326 | }
|
| 323 | 327 | |
| 324 | - if (lastKnownStatus.isOff() && newState.isStarting()) {
|
|
| 328 | + if (_lastKnownStatus.value.isOff() && newState.isStarting()) {
|
|
| 325 | 329 | isTorRestarting = false
|
| 326 | 330 | }
|
| 327 | 331 | |
| 328 | - lastKnownStatus = newState
|
|
| 332 | + _lastKnownStatus.value = newState
|
|
| 329 | 333 | onTorStatusUpdate(null, newStateVal, null)
|
| 330 | 334 | }
|
| 331 | 335 | |
| 332 | 336 | // TorEventsBootstrapStateChangeListener
|
| 333 | 337 | override fun onBootstrapProgress(progress: Double, hasWarnings: Boolean) {
|
| 334 | - Log.d(TAG, "onBootstrapProgress($progress, $hasWarnings)")
|
|
| 335 | - // TODO: onBootstrapProgress should only be used to change the shown
|
|
| 336 | - // bootstrap percentage or a Tor log option during a "Bootstrapping"
|
|
| 337 | - // stage.
|
|
| 338 | - // The progress value should not be used to change the `lastKnownStatus`
|
|
| 339 | - // value or determine if a bootstrap has started or completed. The
|
|
| 340 | - // TorConnectStage should be used instead.
|
|
| 341 | - if (progress == 100.0) {
|
|
| 342 | - lastKnownStatus = TorConnectState.Bootstrapped
|
|
| 343 | - wasTorBootstrapped = true
|
|
| 344 | - onTorConnected()
|
|
| 345 | - } else if (lastKnownStatus == TorConnectState.Bootstrapping) {
|
|
| 346 | - onTorConnecting()
|
|
| 347 | - }
|
|
| 348 | - onTorStatusUpdate("", lastKnownStatus.toTorStatus().status, progress)
|
|
| 338 | + Log.d(TAG, "onBootstrapProgress(progress = $progress, hasWarnings = $hasWarnings)")
|
|
| 339 | + onTorStatusUpdate("", _lastKnownStatus.value.toTorStatus().status, progress)
|
|
| 349 | 340 | }
|
| 350 | 341 | |
| 351 | 342 | // TorEventsBootstrapStateChangeListener
|
| 352 | - override fun onBootstrapComplete() {
|
|
| 353 | - // TODO: There should be no need to respond to the BootstrapComplete
|
|
| 354 | - // event if we are already handling TorConnectStage.Bootstrapped.
|
|
| 355 | - // In particular, `lastKnownStatus` and onTorConnected should be set in
|
|
| 356 | - // response to a change in TorConnectStage instead.
|
|
| 357 | - lastKnownStatus = TorConnectState.Bootstrapped
|
|
| 358 | - this.onTorConnected()
|
|
| 359 | - }
|
|
| 343 | + override fun onBootstrapComplete() = Unit
|
|
| 360 | 344 | |
| 361 | 345 | // TorEventsBootstrapStateChangeListener
|
| 362 | 346 | override fun onBootstrapError(code: String?, message: String?, phase: String?, reason: String?) {
|
| ... | ... | @@ -21,6 +21,12 @@ |
| 21 | 21 | android:paddingStart="16dp"
|
| 22 | 22 | android:paddingEnd="16dp">
|
| 23 | 23 | |
| 24 | + <!--
|
|
| 25 | + TextView below changed as part of tor-browser#43229 to match the designs
|
|
| 26 | + https://www.figma.com/design/vXrWeiV2IlKx5IIZVLtxBX/Android-Components?node-id=1807-3117&t=8Gc1mpPYPQCLMYH2-1 screenshot shown here
|
|
| 27 | + Line spacing eyeballed from screenshot here
|
|
| 28 | + https://gitlab.torproject.org/tpo/applications/tor-browser/-/merge_requests/1275#note_3125666
|
|
| 29 | + -->
|
|
| 24 | 30 | <TextView
|
| 25 | 31 | android:id="@+id/snackbar_text"
|
| 26 | 32 | android:layout_width="0dp"
|
| ... | ... | @@ -29,8 +35,9 @@ |
| 29 | 35 | android:letterSpacing="0.05"
|
| 30 | 36 | android:minHeight="46dp"
|
| 31 | 37 | android:maxLines="2"
|
| 32 | - android:paddingTop="8dp"
|
|
| 33 | - android:paddingBottom="8dp"
|
|
| 38 | + android:paddingTop="12dp"
|
|
| 39 | + android:paddingBottom="12dp"
|
|
| 40 | + android:lineSpacingExtra="8sp"
|
|
| 34 | 41 | android:textAlignment="textStart"
|
| 35 | 42 | android:textColor="@color/photonWhite"
|
| 36 | 43 | android:textSize="18sp"
|
| ... | ... | @@ -27,6 +27,12 @@ |
| 27 | 27 | app:popUpTo="@id/startupFragment"
|
| 28 | 28 | app:popUpToInclusive="true" />
|
| 29 | 29 | |
| 30 | + <action
|
|
| 31 | + android:id="@+id/action_connect_to_tor_before_opening_links"
|
|
| 32 | + app:destination="@+id/torConnectionAssistFragment"
|
|
| 33 | + app:popUpTo="@id/torConnectionAssistFragment"
|
|
| 34 | + app:popUpToInclusive="true"/>
|
|
| 35 | + |
|
| 30 | 36 | <action
|
| 31 | 37 | android:id="@+id/action_global_home"
|
| 32 | 38 | app:destination="@id/homeFragment"
|
| ... | ... | @@ -264,7 +270,7 @@ |
| 264 | 270 | <fragment
|
| 265 | 271 | android:id="@+id/torConnectionAssistFragment"
|
| 266 | 272 | android:name="org.mozilla.fenix.tor.TorConnectionAssistFragment"
|
| 267 | - tools:layout="@layout/fragment_home">
|
|
| 273 | + tools:layout="@layout/fragment_tor_connection_assist">
|
|
| 268 | 274 | <action
|
| 269 | 275 | android:id="@+id/action_home"
|
| 270 | 276 | app:destination="@id/homeFragment"
|
| ... | ... | @@ -149,4 +149,31 @@ |
| 149 | 149 | <string name="connection_assist_final_error_troubleshoot_connection_link">troubleshooting your connection</string>
|
| 150 | 150 | <!-- Connection assist. -->
|
| 151 | 151 | <string name="connection_assist_final_error_learn_more_link">Learn more</string>
|
| 152 | + |
|
| 153 | + <!-- Connection assist. Description for a shown "Snackbar" (special popup notification) with an action to connect -->
|
|
| 154 | + <string name="connection_assist_connect_to_tor_before_opening_links">Connect to Tor before opening links</string>
|
|
| 155 | + <!-- Connection assist. Confirmation button for a shown "Snackbar" (special popup notification) that has a previously mentioned description. Automatically shown in ALL CAPS if available, regardless of the localized string -->
|
|
| 156 | + <string name="connection_assist_connect_to_tor_before_opening_links_confirmation">CONNECT</string>
|
|
| 157 | + |
|
| 158 | + <!-- 2024 YEC. -->
|
|
| 159 | + <string name="YEC_2024_right_to_speak">You have a right to SPEAK without uninvited listeners.</string>
|
|
| 160 | + <!-- 2024 YEC. -->
|
|
| 161 | + <string name="YEC_2024_right_to_BROWSE">You have a right to BROWSE without being watched.</string>
|
|
| 162 | + <!-- 2024 YEC. -->
|
|
| 163 | + <string name="YEC_2024_right_to_SEARCH">You have a right to SEARCH without being followed.</string>
|
|
| 164 | + |
|
| 165 | + <!-- 2024 YEC. -->
|
|
| 166 | + <string name="YEC_2024_donation_encouragement">Join the thousands of Tor supporters building an internet powered by privacy. Make a donation today.</string>
|
|
| 167 | + |
|
| 168 | + <!-- 2024 YEC. -->
|
|
| 169 | + <string name="YEC_2024_donation_match_text">Through December 31, your gift will be matched, up to $300,000!</string>
|
|
| 170 | + |
|
| 171 | + <!-- 2024 YEC. %1$s is the app name "Tor Browser". Since this will only ever show on release, it will always be "Tor Browser" (and not "Tor Browser Alpha" for instance) -->
|
|
| 172 | + <string name="YEC_2024_tor_browser_for_android_will_always_be_free_no_donation_required">%1$s for Android will always be free to use—no donation is required to use this app.</string>
|
|
| 173 | + |
|
| 174 | + <!-- 2024 YEC. Accessible name for the "X" button. -->
|
|
| 175 | + <string name="YEC_2024_close">Close</string>
|
|
| 176 | + |
|
| 177 | + <!-- 2024 YEC. -->
|
|
| 178 | + <string name="YEC_2024_donate_now">Donate now</string>
|
|
| 152 | 179 | </resources> |