Dan Ballard pushed to branch tor-browser-128.8.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
d3a9fcd2
by clairehurst at 2025-03-10T10:52:05-06:00
6 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/tor/TorBootstrapProgressViewModel.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/UrlQuickLoadViewModel.kt
Changes:
... | ... | @@ -155,7 +155,7 @@ import java.util.Locale |
155 | 155 | import mozilla.components.browser.engine.gecko.GeckoEngine
|
156 | 156 | import org.mozilla.fenix.components.FenixSnackbar
|
157 | 157 | import org.mozilla.fenix.home.HomeFragment
|
158 | -import org.mozilla.fenix.tor.TorConnectionAssistViewModel
|
|
158 | +import org.mozilla.fenix.tor.UrlQuickLoadViewModel
|
|
159 | 159 | import org.mozilla.geckoview.TorAndroidIntegration
|
160 | 160 | |
161 | 161 | /**
|
... | ... | @@ -237,7 +237,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorAn |
237 | 237 | |
238 | 238 | private var dialog: RedirectDialogFragment? = null
|
239 | 239 | |
240 | - private val torConnectionAssistViewModel: TorConnectionAssistViewModel by viewModels()
|
|
240 | + private val urlQuickLoadViewModel: UrlQuickLoadViewModel by viewModels()
|
|
241 | 241 | |
242 | 242 | @Suppress("ComplexMethod")
|
243 | 243 | final override fun onCreate(savedInstanceState: Bundle?) {
|
... | ... | @@ -1124,7 +1124,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorAn |
1124 | 1124 | .setText(getString(R.string.connection_assist_connect_to_tor_before_opening_links))
|
1125 | 1125 | .setAllCapsForActionButton(false)
|
1126 | 1126 | .setAction(getString(R.string.connection_assist_connect_to_tor_before_opening_links_confirmation)) {
|
1127 | - torConnectionAssistViewModel.handleConnect(searchTermOrURL)
|
|
1127 | + urlQuickLoadViewModel.urlToLoadAfterConnecting.value = searchTermOrURL
|
|
1128 | 1128 | if (navHost.navController.previousBackStackEntry?.destination?.id == R.id.torConnectionAssistFragment) {
|
1129 | 1129 | supportFragmentManager.popBackStack()
|
1130 | 1130 | } else {
|
... | ... | @@ -158,13 +158,14 @@ import org.mozilla.fenix.search.toolbar.SearchSelectorMenu |
158 | 158 | import org.mozilla.fenix.tabstray.Page
|
159 | 159 | import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
|
160 | 160 | import org.mozilla.fenix.theme.FirefoxTheme
|
161 | -import org.mozilla.fenix.tor.TorConnectionAssistViewModel
|
|
162 | 161 | import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
|
163 | 162 | import org.mozilla.fenix.utils.allowUndo
|
164 | 163 | import org.mozilla.fenix.wallpapers.Wallpaper
|
165 | 164 | import java.lang.ref.WeakReference
|
166 | 165 | import org.mozilla.fenix.GleanMetrics.TabStrip as TabStripMetrics
|
167 | 166 | |
167 | +import org.mozilla.fenix.tor.UrlQuickLoadViewModel
|
|
168 | + |
|
168 | 169 | @Suppress("TooManyFunctions", "LargeClass")
|
169 | 170 | class HomeFragment : Fragment(), UserInteractionHandler {
|
170 | 171 | private val args by navArgs<HomeFragmentArgs>()
|
... | ... | @@ -178,7 +179,7 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
178 | 179 | private val binding get() = _binding!!
|
179 | 180 | |
180 | 181 | private val homeViewModel: HomeScreenViewModel by activityViewModels()
|
181 | - private val torConnectionAssistViewModel: TorConnectionAssistViewModel by activityViewModels()
|
|
182 | + private val urlQuickLoadViewModel: UrlQuickLoadViewModel by activityViewModels()
|
|
182 | 183 | |
183 | 184 | private val snackbarAnchorView: View?
|
184 | 185 | get() = when (requireContext().settings().toolbarPosition) {
|
... | ... | @@ -892,14 +893,15 @@ class HomeFragment : Fragment(), UserInteractionHandler { |
892 | 893 | view = view,
|
893 | 894 | )
|
894 | 895 | |
895 | - torConnectionAssistViewModel.urlToLoadAfterConnecting.also {
|
|
896 | - if(!it.isNullOrBlank()){
|
|
896 | + urlQuickLoadViewModel.urlToLoadAfterConnecting.observe(viewLifecycleOwner) {
|
|
897 | + if (!it.isNullOrBlank()) {
|
|
897 | 898 | (requireActivity() as HomeActivity).openToBrowserAndLoad(
|
898 | 899 | searchTermOrURL = it,
|
899 | 900 | newTab = true,
|
900 | 901 | from = BrowserDirection.FromHome,
|
901 | 902 | )
|
902 | - torConnectionAssistViewModel.urlToLoadAfterConnecting = null // Only load this url once
|
|
903 | + // Only load this url once
|
|
904 | + urlQuickLoadViewModel.urlToLoadAfterConnecting.value = null
|
|
903 | 905 | }
|
904 | 906 | }
|
905 | 907 |
1 | +package org.mozilla.fenix.tor
|
|
2 | + |
|
3 | +import android.app.Application
|
|
4 | +import androidx.lifecycle.AndroidViewModel
|
|
5 | +import androidx.lifecycle.MutableLiveData
|
|
6 | +import org.mozilla.fenix.ext.components
|
|
7 | +import org.mozilla.geckoview.TorAndroidIntegration.BootstrapStateChangeListener
|
|
8 | + |
|
9 | +class TorBootstrapProgressViewModel(
|
|
10 | + application: Application,
|
|
11 | +) : AndroidViewModel(application), BootstrapStateChangeListener {
|
|
12 | + |
|
13 | + private val torIntegrationAndroid =
|
|
14 | + application.components.core.geckoRuntime.torIntegrationController
|
|
15 | + |
|
16 | + val progress: MutableLiveData<Int> by lazy {
|
|
17 | + MutableLiveData<Int>(0)
|
|
18 | + }
|
|
19 | + |
|
20 | + init {
|
|
21 | + torIntegrationAndroid.registerBootstrapStateChangeListener(this)
|
|
22 | + }
|
|
23 | + |
|
24 | + override fun onCleared() {
|
|
25 | + torIntegrationAndroid.unregisterBootstrapStateChangeListener(this)
|
|
26 | + super.onCleared()
|
|
27 | + }
|
|
28 | + |
|
29 | + override fun onBootstrapStateChange(state: String?) {}
|
|
30 | + |
|
31 | + override fun onBootstrapProgress(progress: Double, hasWarnings: Boolean) {
|
|
32 | + this.progress.value = progress.toInt()
|
|
33 | + }
|
|
34 | + |
|
35 | + override fun onBootstrapComplete() {}
|
|
36 | + |
|
37 | + override fun onBootstrapError(
|
|
38 | + code: String?,
|
|
39 | + message: String?,
|
|
40 | + phase: String?,
|
|
41 | + reason: String?,
|
|
42 | + ) {
|
|
43 | + }
|
|
44 | +} |
... | ... | @@ -35,12 +35,14 @@ import org.mozilla.fenix.ext.hideToolbar |
35 | 35 | class TorConnectionAssistFragment : Fragment(), UserInteractionHandler {
|
36 | 36 | |
37 | 37 | private val TAG = "TorConnectionAssistFrag"
|
38 | - private val viewModel: TorConnectionAssistViewModel by activityViewModels()
|
|
38 | + private val progressViewModel: TorBootstrapProgressViewModel by viewModels()
|
|
39 | + private val quickstartViewModel: QuickstartViewModel by activityViewModels()
|
|
40 | + private val torConnectionAssistViewModel : TorConnectionAssistViewModel by viewModels()
|
|
41 | + private val urlQuickLoadViewModel : UrlQuickLoadViewModel by activityViewModels()
|
|
42 | + |
|
39 | 43 | private var _binding: FragmentTorConnectionAssistBinding? = null
|
40 | 44 | private val binding get() = _binding!!
|
41 | 45 | |
42 | - private val quickstartViewModel: QuickstartViewModel by activityViewModels()
|
|
43 | - |
|
44 | 46 | override fun onCreateView(
|
45 | 47 | inflater: LayoutInflater,
|
46 | 48 | container: ViewGroup?,
|
... | ... | @@ -49,18 +51,23 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
49 | 51 | _binding = FragmentTorConnectionAssistBinding.inflate(
|
50 | 52 | inflater, container, false,
|
51 | 53 | )
|
54 | + |
|
52 | 55 | viewLifecycleOwner.lifecycleScope.launch {
|
53 | 56 | repeatOnLifecycle(Lifecycle.State.STARTED) {
|
54 | - viewModel.collectLastKnownStatus()
|
|
57 | + torConnectionAssistViewModel.collectLastKnownStatus()
|
|
55 | 58 | }
|
56 | 59 | }
|
57 | 60 | |
58 | - viewLifecycleOwner.lifecycleScope.launch {
|
|
59 | - repeatOnLifecycle(Lifecycle.State.STARTED) {
|
|
60 | - viewModel.torConnectScreen.collect { screen ->
|
|
61 | - Log.d(TAG, "torConnectScreen is $screen")
|
|
62 | - showScreen(screen)
|
|
63 | - }
|
|
61 | + torConnectionAssistViewModel.shouldOpenHome.observe(viewLifecycleOwner) {
|
|
62 | + Log.d(TAG, "shouldOpenHome = $it")
|
|
63 | + if (it) {
|
|
64 | + openHome()
|
|
65 | + }
|
|
66 | + }
|
|
67 | + |
|
68 | + urlQuickLoadViewModel.urlToLoadAfterConnecting.observe(viewLifecycleOwner) { url ->
|
|
69 | + if (!url.isNullOrBlank()) {
|
|
70 | + torConnectionAssistViewModel.handleConnect()
|
|
64 | 71 | }
|
65 | 72 | }
|
66 | 73 | |
... | ... | @@ -75,10 +82,13 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
75 | 82 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
76 | 83 | super.onViewCreated(view, savedInstanceState)
|
77 | 84 | |
78 | - viewModel.progress().observe(
|
|
79 | - viewLifecycleOwner,
|
|
80 | - ) { progress ->
|
|
81 | - setProgressBarCompat(progress)
|
|
85 | + viewLifecycleOwner.lifecycleScope.launch {
|
|
86 | + repeatOnLifecycle(Lifecycle.State.STARTED) {
|
|
87 | + torConnectionAssistViewModel.torConnectScreen.collect { screen ->
|
|
88 | + Log.d(TAG, "torConnectScreen is $screen")
|
|
89 | + showScreen(screen)
|
|
90 | + }
|
|
91 | + }
|
|
82 | 92 | }
|
83 | 93 | |
84 | 94 | quickstartViewModel.quickstart().observe(
|
... | ... | @@ -87,13 +97,10 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
87 | 97 | binding.quickstartSwitch.isChecked = it
|
88 | 98 | }
|
89 | 99 | |
90 | - viewModel.shouldOpenHome().observe(
|
|
100 | + progressViewModel.progress.observe(
|
|
91 | 101 | viewLifecycleOwner,
|
92 | - ) {
|
|
93 | - Log.d(TAG, "shouldOpenHome() = $it")
|
|
94 | - if (it) {
|
|
95 | - openHome()
|
|
96 | - }
|
|
102 | + ) { progress ->
|
|
103 | + setProgressBarCompat(progress)
|
|
97 | 104 | }
|
98 | 105 | |
99 | 106 | }
|
... | ... | @@ -142,7 +149,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
142 | 149 | private fun setBackButton(screen: ConnectAssistUiState) {
|
143 | 150 | binding.backButton.visibility = if (screen.backButtonVisible) View.VISIBLE else View.INVISIBLE
|
144 | 151 | binding.backButton.setOnClickListener {
|
145 | - viewModel.handleBackButtonPressed()
|
|
152 | + torConnectionAssistViewModel.handleBackButtonPressed()
|
|
146 | 153 | }
|
147 | 154 | }
|
148 | 155 | |
... | ... | @@ -204,10 +211,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
204 | 211 | if (screen.torBootstrapButton1Visible) View.VISIBLE else View.GONE
|
205 | 212 | binding.torBootstrapButton1.text = getString(screen.torBootstrapButton1TextStringResource)
|
206 | 213 | binding.torBootstrapButton1.setOnClickListener {
|
207 | - viewModel.handleButton1Pressed(
|
|
208 | - screen,
|
|
209 | - lifecycleScope,
|
|
210 | - )
|
|
214 | + torConnectionAssistViewModel.handleConnect()
|
|
211 | 215 | }
|
212 | 216 | }
|
213 | 217 | |
... | ... | @@ -231,7 +235,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
231 | 235 | }
|
232 | 236 | }
|
233 | 237 | binding.torBootstrapButton2.setOnClickListener {
|
234 | - viewModel.cancelTorBootstrap()
|
|
238 | + torConnectionAssistViewModel.cancelTorBootstrap()
|
|
235 | 239 | if (screen.torBootstrapButton2ShouldOpenSettings) {
|
236 | 240 | openTorConnectionSettings()
|
237 | 241 | } else if (screen.torBootstrapButton2ShouldRestartApp) {
|
... | ... | @@ -279,7 +283,9 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
279 | 283 | |
280 | 284 | private fun openHome() {
|
281 | 285 | Log.d(TAG, "openHome()")
|
282 | - viewModel.openHome(findNavController())
|
|
286 | + findNavController().navigate(
|
|
287 | + TorConnectionAssistFragmentDirections.actionHome(),
|
|
288 | + )
|
|
283 | 289 | }
|
284 | 290 | |
285 | 291 | private fun openSettings(preferenceToScrollTo: String? = null) {
|
... | ... | @@ -308,7 +314,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
308 | 314 | }
|
309 | 315 | |
310 | 316 | override fun onBackPressed(): Boolean {
|
311 | - return viewModel.handleBackButtonPressed()
|
|
317 | + return torConnectionAssistViewModel.handleBackButtonPressed()
|
|
312 | 318 | }
|
313 | 319 | |
314 | 320 | } |
... | ... | @@ -7,91 +7,42 @@ package org.mozilla.fenix.tor |
7 | 7 | import android.app.Application
|
8 | 8 | import android.util.Log
|
9 | 9 | import androidx.lifecycle.AndroidViewModel
|
10 | -import androidx.lifecycle.LifecycleCoroutineScope
|
|
11 | -import androidx.lifecycle.LiveData
|
|
12 | 10 | import androidx.lifecycle.MutableLiveData
|
13 | -import androidx.navigation.NavController
|
|
14 | 11 | import kotlinx.coroutines.flow.MutableStateFlow
|
15 | 12 | import kotlinx.coroutines.flow.StateFlow
|
16 | 13 | import org.mozilla.fenix.ext.components
|
17 | 14 | |
18 | 15 | class TorConnectionAssistViewModel(
|
19 | 16 | application: Application,
|
20 | -) : AndroidViewModel(application), TorEvents {
|
|
17 | +) : AndroidViewModel(application) {
|
|
21 | 18 | |
22 | 19 | private val TAG = "torConnectionAssistVM"
|
23 | - private val components = getApplication<Application>().components
|
|
24 | - |
|
25 | - private val _torController: TorControllerGV = components.torController
|
|
20 | + private val torIntegrationAndroid =
|
|
21 | + application.components.core.geckoRuntime.torIntegrationController
|
|
22 | + private val _torController: TorControllerGV = application.components.torController
|
|
26 | 23 | |
27 | 24 | private val _torConnectScreen = MutableStateFlow(ConnectAssistUiState.Splash)
|
28 | 25 | internal val torConnectScreen: StateFlow<ConnectAssistUiState> = _torConnectScreen
|
29 | 26 | |
30 | - private val _shouldOpenHome = MutableLiveData(false)
|
|
31 | - fun shouldOpenHome(): LiveData<Boolean> {
|
|
32 | - return _shouldOpenHome
|
|
33 | - }
|
|
34 | - |
|
35 | - private val _progress = MutableLiveData(0)
|
|
36 | - fun progress(): LiveData<Int> {
|
|
37 | - return _progress
|
|
38 | - }
|
|
39 | - |
|
40 | - init {
|
|
41 | - Log.d(TAG, "initiating TorConnectionAssistViewModel $this")
|
|
42 | - _torController.registerTorListener(this)
|
|
43 | - }
|
|
44 | - |
|
45 | - var urlToLoadAfterConnecting: String? = null
|
|
46 | - |
|
47 | - fun handleConnect(
|
|
48 | - urlToLoadAfterConnecting: String? = null,
|
|
49 | - withDebugLogging: Boolean = false,
|
|
50 | - lifecycleScope: LifecycleCoroutineScope? = null,
|
|
51 | - ) {
|
|
52 | - this.urlToLoadAfterConnecting = urlToLoadAfterConnecting
|
|
53 | - if (_torController.lastKnownStatus.value.isOff()) {
|
|
54 | - Log.d(TAG, "handleConnect() triggered, initiatingTorBootstrap")
|
|
55 | - _torController.initiateTorBootstrap(
|
|
56 | - withDebugLogging = withDebugLogging,
|
|
57 | - lifecycleScope = lifecycleScope,
|
|
58 | - )
|
|
59 | - }
|
|
27 | + val shouldOpenHome: MutableLiveData<Boolean> by lazy {
|
|
28 | + MutableLiveData(false)
|
|
60 | 29 | }
|
61 | 30 | |
62 | - fun handleButton1Pressed(
|
|
63 | - screen: ConnectAssistUiState,
|
|
64 | - lifecycleScope: LifecycleCoroutineScope?,
|
|
65 | - ) {
|
|
66 | - if (screen.torBootstrapButton1ShouldShowTryingABridge) {
|
|
31 | + fun handleConnect() {
|
|
32 | + if (_torConnectScreen.value.torBootstrapButton1ShouldShowTryingABridge) {
|
|
67 | 33 | tryABridge()
|
68 | 34 | } else {
|
69 | - handleConnect(lifecycleScope = lifecycleScope)
|
|
35 | + if (_torController.lastKnownStatus.value.isOff()) {
|
|
36 | + torIntegrationAndroid.beginBootstrap()
|
|
37 | + }
|
|
70 | 38 | }
|
71 | 39 | }
|
72 | 40 | |
73 | 41 | fun cancelTorBootstrap() {
|
74 | - _torController.stopTor()
|
|
42 | + torIntegrationAndroid.cancelBootstrap()
|
|
75 | 43 | _torController.setTorStopped()
|
76 | 44 | }
|
77 | 45 | |
78 | - override fun onTorConnecting() {
|
|
79 | - Log.d(TAG, "onTorConnecting()")
|
|
80 | - }
|
|
81 | - |
|
82 | - override fun onTorConnected() {
|
|
83 | - Log.d(TAG, "onTorConnected()")
|
|
84 | - _torController.unregisterTorListener(this)
|
|
85 | - }
|
|
86 | - |
|
87 | - override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) {
|
|
88 | - Log.d(TAG, "onTorStatusUpdate($entry, $status, $progress)")
|
|
89 | - if (progress != null) {
|
|
90 | - _progress.value = progress.toInt()
|
|
91 | - }
|
|
92 | - |
|
93 | - }
|
|
94 | - |
|
95 | 46 | suspend fun collectLastKnownStatus() {
|
96 | 47 | _torController.lastKnownStatus.collect {
|
97 | 48 | when (it) {
|
... | ... | @@ -99,8 +50,8 @@ class TorConnectionAssistViewModel( |
99 | 50 | TorConnectState.Configuring -> handleConfiguring()
|
100 | 51 | TorConnectState.AutoBootstrapping -> handleBootstrap()
|
101 | 52 | TorConnectState.Bootstrapping -> handleBootstrap()
|
102 | - TorConnectState.Bootstrapped -> _shouldOpenHome.value = true
|
|
103 | - TorConnectState.Disabled -> _shouldOpenHome.value = true
|
|
53 | + TorConnectState.Bootstrapped -> shouldOpenHome.value = true
|
|
54 | + TorConnectState.Disabled -> shouldOpenHome.value = true
|
|
104 | 55 | TorConnectState.Error -> handleError()
|
105 | 56 | }
|
106 | 57 | }
|
... | ... | @@ -145,10 +96,7 @@ class TorConnectionAssistViewModel( |
145 | 96 | }
|
146 | 97 | |
147 | 98 | else -> _torConnectScreen.value =
|
148 | - ConnectAssistUiState.Connecting.also { connectAssistUiState ->
|
|
149 | - // covers the case of when the bootstrap is already in progress when the UiState "catches up"
|
|
150 | - connectAssistUiState.progress = _progress.value ?: 0
|
|
151 | - }
|
|
99 | + ConnectAssistUiState.Connecting
|
|
152 | 100 | }
|
153 | 101 | }
|
154 | 102 | |
... | ... | @@ -184,10 +132,6 @@ class TorConnectionAssistViewModel( |
184 | 132 | _torConnectScreen.value = ConnectAssistUiState.InternetError
|
185 | 133 | }
|
186 | 134 | |
187 | - override fun onTorStopped() {
|
|
188 | - Log.d(TAG, "onTorStopped()")
|
|
189 | - }
|
|
190 | - |
|
191 | 135 | private fun tryABridge() {
|
192 | 136 | if (!locationFound()) {
|
193 | 137 | _torConnectScreen.value = ConnectAssistUiState.LocationError
|
... | ... | @@ -198,7 +142,7 @@ class TorConnectionAssistViewModel( |
198 | 142 | _torController.bridgeTransport =
|
199 | 143 | TorBridgeTransportConfig.BUILTIN_SNOWFLAKE // TODO select based on country
|
200 | 144 | }
|
201 | - handleConnect(withDebugLogging = true)
|
|
145 | + torIntegrationAndroid.beginBootstrap()
|
|
202 | 146 | }
|
203 | 147 | |
204 | 148 | private fun locationFound(): Boolean {
|
... | ... | @@ -249,10 +193,4 @@ class TorConnectionAssistViewModel( |
249 | 193 | }
|
250 | 194 | return true
|
251 | 195 | }
|
252 | - |
|
253 | - fun openHome(navController: NavController) {
|
|
254 | - navController.navigate(
|
|
255 | - TorConnectionAssistFragmentDirections.actionHome(),
|
|
256 | - )
|
|
257 | - }
|
|
258 | 196 | } |
1 | +package org.mozilla.fenix.tor
|
|
2 | + |
|
3 | +import androidx.lifecycle.MutableLiveData
|
|
4 | +import androidx.lifecycle.ViewModel
|
|
5 | + |
|
6 | +class UrlQuickLoadViewModel : ViewModel() {
|
|
7 | + val urlToLoadAfterConnecting: MutableLiveData<String?> by lazy {
|
|
8 | + MutableLiveData<String?>(null)
|
|
9 | + }
|
|
10 | +} |