Dan Ballard pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android
Commits:
-
dd7c3469
by Dan Ballard at 2024-03-27T13:30:32-07:00
13 changed files:
- fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
- − fenix/app/src/main/java/org/mozilla/fenix/settings/TorNetworkSettingsFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/tor/TorController.kt
- fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerGV.kt
- fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerTAS.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorLogsFragment.kt
- fenix/app/src/main/res/navigation/nav_graph.xml
- fenix/app/src/main/res/values/preference_keys.xml
- fenix/app/src/main/res/values/torbrowser_strings.xml
- fenix/app/src/main/res/xml/preferences.xml
- − fenix/app/src/main/res/xml/tor_network_settings_preferences.xml
Changes:
... | ... | @@ -61,6 +61,8 @@ import org.mozilla.fenix.ext.showToolbar |
61 | 61 | import org.mozilla.fenix.nimbus.FxNimbus
|
62 | 62 | import org.mozilla.fenix.perf.ProfilerViewModel
|
63 | 63 | import org.mozilla.fenix.settings.account.AccountUiView
|
64 | +import org.mozilla.fenix.tor.TorBridgeTransportConfig
|
|
65 | +import org.mozilla.fenix.tor.TorEvents
|
|
64 | 66 | import org.mozilla.fenix.utils.Settings
|
65 | 67 | import kotlin.system.exitProcess
|
66 | 68 | |
... | ... | @@ -155,6 +157,8 @@ class SettingsFragment : PreferenceFragmentCompat() { |
155 | 157 | }
|
156 | 158 | |
157 | 159 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
160 | + //setPreferencesFromResource(R.xml.tor_network_settings_preferences, rootKey)
|
|
161 | + //setupConnectionPreferences()
|
|
158 | 162 | setPreferencesFromResource(R.xml.preferences, rootKey)
|
159 | 163 | }
|
160 | 164 | |
... | ... | @@ -178,7 +182,10 @@ class SettingsFragment : PreferenceFragmentCompat() { |
178 | 182 | update(shouldUpdateAccountUIState = !creatingFragment)
|
179 | 183 | |
180 | 184 | requireView().findViewById<RecyclerView>(R.id.recycler_view)
|
181 | - ?.hideInitialScrollBar(viewLifecycleOwner.lifecycleScope)
|
|
185 | + .also {
|
|
186 | + it?.hideInitialScrollBar(viewLifecycleOwner.lifecycleScope)
|
|
187 | + it?.disableHidingAnimation()
|
|
188 | + }
|
|
182 | 189 | |
183 | 190 | if (args.preferenceToScrollTo != null) {
|
184 | 191 | scrollToPreference(args.preferenceToScrollTo)
|
... | ... | @@ -277,9 +284,6 @@ class SettingsFragment : PreferenceFragmentCompat() { |
277 | 284 | resources.getString(R.string.pref_key_search_settings) -> {
|
278 | 285 | SettingsFragmentDirections.actionSettingsFragmentToSearchEngineFragment()
|
279 | 286 | }
|
280 | - resources.getString(R.string.pref_key_tor_network_settings) -> {
|
|
281 | - SettingsFragmentDirections.actionSettingsFragmentToTorNetworkSettingsFragment()
|
|
282 | - }
|
|
283 | 287 | resources.getString(R.string.pref_key_tor_security_level_settings) -> {
|
284 | 288 | SettingsFragmentDirections.actionSettingsFragmentToTorSecurityLevelFragment()
|
285 | 289 | }
|
... | ... | @@ -523,6 +527,7 @@ class SettingsFragment : PreferenceFragmentCompat() { |
523 | 527 | preferenceStartProfiler?.isVisible = showSecretDebugMenuThisSession &&
|
524 | 528 | (requireContext().components.core.engine.profiler?.isProfilerActive() != null)
|
525 | 529 | }
|
530 | + |
|
526 | 531 | setupCookieBannerPreference()
|
527 | 532 | setupAmoCollectionOverridePreference(requireContext().settings())
|
528 | 533 | setupGeckoLogsPreference(requireContext().settings())
|
... | ... | @@ -532,6 +537,7 @@ class SettingsFragment : PreferenceFragmentCompat() { |
532 | 537 | setupSearchPreference()
|
533 | 538 | setupHomepagePreference()
|
534 | 539 | setupTrackingProtectionPreference()
|
540 | + setupConnectionPreferences()
|
|
535 | 541 | }
|
536 | 542 | |
537 | 543 | /**
|
... | ... | @@ -566,6 +572,10 @@ class SettingsFragment : PreferenceFragmentCompat() { |
566 | 572 | }
|
567 | 573 | }
|
568 | 574 | |
575 | + private fun RecyclerView.disableHidingAnimation() {
|
|
576 | + this.setItemAnimator(null)
|
|
577 | + this.setLayoutAnimation(null)
|
|
578 | + }
|
|
569 | 579 | private fun updateFxAAllowDomesticChinaServerMenu() {
|
570 | 580 | val settings = requireContext().settings()
|
571 | 581 | val preferenceAllowDomesticChinaServer =
|
... | ... | @@ -705,6 +715,39 @@ class SettingsFragment : PreferenceFragmentCompat() { |
705 | 715 | }
|
706 | 716 | }
|
707 | 717 | |
718 | + internal fun setupConnectionPreferences() {
|
|
719 | + // will be needed for phase2
|
|
720 | + //val torController = requireContext().components.torController
|
|
721 | + |
|
722 | + requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridge_config).apply {
|
|
723 | + setOnPreferenceClickListener {
|
|
724 | + val directions =
|
|
725 | + SettingsFragmentDirections
|
|
726 | + .actionSettingsFragmentToTorBridgeConfigFragment()
|
|
727 | + requireView().findNavController().navigate(directions)
|
|
728 | + true
|
|
729 | + }
|
|
730 | + }
|
|
731 | + |
|
732 | + requirePreference<Preference>(R.string.pref_key_use_new_bootstrap).apply {
|
|
733 | + setOnPreferenceClickListener {
|
|
734 | + val directions =
|
|
735 | + SettingsFragmentDirections.actionSettingsFragmentToBetaConnectionFeaturesFragment()
|
|
736 | + requireView().findNavController().navigate(directions)
|
|
737 | + true
|
|
738 | + }
|
|
739 | + }
|
|
740 | + |
|
741 | + requirePreference<Preference>(R.string.pref_key_tor_logs).apply {
|
|
742 | + setOnPreferenceClickListener {
|
|
743 | + val directions =
|
|
744 | + SettingsFragmentDirections.actionSettingsFragmentToTorLogsFragment()
|
|
745 | + requireView().findNavController().navigate(directions)
|
|
746 | + true
|
|
747 | + }
|
|
748 | + }
|
|
749 | + }
|
|
750 | + |
|
708 | 751 | @VisibleForTesting
|
709 | 752 | internal fun setupCookieBannerPreference() {
|
710 | 753 | with(requirePreference<Preference>(R.string.pref_key_cookie_banner_settings)) {
|
1 | -/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2 | - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3 | - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4 | - |
|
5 | -package org.mozilla.fenix.settings
|
|
6 | - |
|
7 | -import android.os.Bundle
|
|
8 | -import androidx.navigation.findNavController
|
|
9 | -import androidx.preference.Preference
|
|
10 | -import androidx.preference.PreferenceFragmentCompat
|
|
11 | -import org.mozilla.fenix.R
|
|
12 | -import org.mozilla.fenix.ext.components
|
|
13 | -import org.mozilla.fenix.ext.nav
|
|
14 | -import org.mozilla.fenix.ext.settings
|
|
15 | -import org.mozilla.fenix.ext.showToolbar
|
|
16 | -import org.mozilla.fenix.tor.TorBridgeTransportConfig
|
|
17 | -import org.mozilla.fenix.tor.TorEvents
|
|
18 | - |
|
19 | -/**
|
|
20 | - * Lets the user configure Tor network connection settings
|
|
21 | - */
|
|
22 | -class TorNetworkSettingsFragment : PreferenceFragmentCompat(), TorEvents {
|
|
23 | - override fun onResume() {
|
|
24 | - super.onResume()
|
|
25 | - |
|
26 | - val torController = requireContext().components.torController
|
|
27 | - |
|
28 | - torController.registerTorListener(this)
|
|
29 | - |
|
30 | - showToolbar(getString(R.string.preferences_tor_network_settings))
|
|
31 | - |
|
32 | - val yesString = getString(R.string.preferences_tor_network_settings_yes)
|
|
33 | - val noString = getString(R.string.preferences_tor_network_settings_no)
|
|
34 | - |
|
35 | - requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridge_config).apply {
|
|
36 | - setOnPreferenceClickListener {
|
|
37 | - val directions =
|
|
38 | - TorNetworkSettingsFragmentDirections
|
|
39 | - .actionTorNetworkSettingsFragmentToTorBridgeConfigFragment()
|
|
40 | - requireView().findNavController().navigate(directions)
|
|
41 | - true
|
|
42 | - }
|
|
43 | - |
|
44 | - if (torController.bridgesEnabled) {
|
|
45 | - if (torController.bridgeTransport == TorBridgeTransportConfig.USER_PROVIDED) {
|
|
46 | - summary =
|
|
47 | - getString(
|
|
48 | - R
|
|
49 | - .string
|
|
50 | - .preferences_tor_network_settings_bridge_config_description_user_provided_enabled
|
|
51 | - )
|
|
52 | - } else {
|
|
53 | - summary =
|
|
54 | - getString(
|
|
55 | - R
|
|
56 | - .string
|
|
57 | - .preferences_tor_network_settings_bridge_config_description_builtin_transport_enabled
|
|
58 | - )
|
|
59 | - }
|
|
60 | - } else {
|
|
61 | - summary =
|
|
62 | - getString(
|
|
63 | - R
|
|
64 | - .string
|
|
65 | - .preferences_tor_network_settings_bridge_config_description
|
|
66 | - )
|
|
67 | - }
|
|
68 | - }
|
|
69 | - |
|
70 | - requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridges_enabled).apply {
|
|
71 | - val formatStringRes = R.string.preferences_tor_network_settings_bridges_enabled
|
|
72 | - title = if (torController.bridgesEnabled) {
|
|
73 | - getString(formatStringRes, yesString)
|
|
74 | - } else {
|
|
75 | - getString(formatStringRes, noString)
|
|
76 | - }
|
|
77 | - }
|
|
78 | - |
|
79 | - requirePreference<Preference>(R.string.pref_key_use_new_bootstrap).apply {
|
|
80 | - setOnPreferenceClickListener {
|
|
81 | - val directions =
|
|
82 | - TorNetworkSettingsFragmentDirections.actionTorNetworkSettingsFragmentToBetaConnectionFeaturesFragment()
|
|
83 | - requireView().findNavController().navigate(directions)
|
|
84 | - true
|
|
85 | - }
|
|
86 | - }
|
|
87 | - |
|
88 | - setStatus()
|
|
89 | - }
|
|
90 | - |
|
91 | - private fun setStatus() {
|
|
92 | - val torController = requireContext().components.torController
|
|
93 | - val yesString = getString(R.string.preferences_tor_network_settings_yes)
|
|
94 | - val noString = getString(R.string.preferences_tor_network_settings_no)
|
|
95 | - |
|
96 | - requirePreference<Preference>(R.string.pref_key_tor_network_settings_tor_ready).apply {
|
|
97 | - val formatStringRes = R.string.preferences_tor_network_settings_tor_ready
|
|
98 | - @SuppressWarnings("ComplexCondition")
|
|
99 | - title = if (!torController.isStarting &&
|
|
100 | - torController.isConnected &&
|
|
101 | - torController.isBootstrapped &&
|
|
102 | - !torController.isRestarting) {
|
|
103 | - getString(formatStringRes, yesString)
|
|
104 | - } else {
|
|
105 | - getString(formatStringRes, noString)
|
|
106 | - }
|
|
107 | - }
|
|
108 | - |
|
109 | - requirePreference<Preference>(R.string.pref_key_tor_network_settings_state).apply {
|
|
110 | - val formatStringRes = R.string.preferences_tor_network_settings_state
|
|
111 | - |
|
112 | - title = if (torController.isRestarting) {
|
|
113 | - getString(formatStringRes,
|
|
114 | - getString(
|
|
115 | - R
|
|
116 | - .string
|
|
117 | - .preferences_tor_network_settings_restarting
|
|
118 | - )
|
|
119 | - )
|
|
120 | - } else if (torController.isStarting) {
|
|
121 | - getString(formatStringRes,
|
|
122 | - getString(
|
|
123 | - R
|
|
124 | - .string
|
|
125 | - .preferences_tor_network_settings_connecting
|
|
126 | - )
|
|
127 | - )
|
|
128 | - } else if (torController.isConnected) {
|
|
129 | - getString(formatStringRes,
|
|
130 | - getString(
|
|
131 | - R
|
|
132 | - .string
|
|
133 | - .preferences_tor_network_settings_connected
|
|
134 | - )
|
|
135 | - )
|
|
136 | - } else {
|
|
137 | - getString(formatStringRes,
|
|
138 | - getString(
|
|
139 | - R
|
|
140 | - .string
|
|
141 | - .preferences_tor_network_settings_disconnected
|
|
142 | - )
|
|
143 | - )
|
|
144 | - }
|
|
145 | - }
|
|
146 | - }
|
|
147 | - |
|
148 | - override fun onStop() {
|
|
149 | - super.onStop()
|
|
150 | - requireContext().components.torController.unregisterTorListener(this)
|
|
151 | - }
|
|
152 | - |
|
153 | - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
154 | - setPreferencesFromResource(R.xml.tor_network_settings_preferences, rootKey)
|
|
155 | - }
|
|
156 | - |
|
157 | - @SuppressWarnings("EmptyFunctionBlock")
|
|
158 | - override fun onTorConnecting() {
|
|
159 | - }
|
|
160 | - |
|
161 | - @SuppressWarnings("EmptyFunctionBlock")
|
|
162 | - override fun onTorConnected() {
|
|
163 | - }
|
|
164 | - |
|
165 | - @SuppressWarnings("EmptyFunctionBlock")
|
|
166 | - override fun onTorStopped() {
|
|
167 | - }
|
|
168 | - |
|
169 | - override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) {
|
|
170 | - setStatus()
|
|
171 | - }
|
|
172 | -} |
... | ... | @@ -19,6 +19,7 @@ import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor |
19 | 19 | import androidx.navigation.fragment.findNavController
|
20 | 20 | import com.google.android.material.appbar.AppBarLayout
|
21 | 21 | import org.mozilla.fenix.HomeActivity
|
22 | +import org.mozilla.fenix.R
|
|
22 | 23 | import org.mozilla.fenix.ext.components
|
23 | 24 | import org.mozilla.fenix.ext.hideToolbar
|
24 | 25 | import org.mozilla.fenix.ext.settings
|
... | ... | @@ -182,7 +183,9 @@ class TorBootstrapFragment : Fragment() { |
182 | 183 | |
183 | 184 | private fun openTorNetworkSettings() {
|
184 | 185 | val directions =
|
185 | - TorBootstrapFragmentDirections.actionTorbootstrapFragmentToTorNetworkSettingsFragment()
|
|
186 | + TorBootstrapFragmentDirections.actionTorbootstrapFragmentToSettingsFragment(
|
|
187 | + requireContext().getString(R.string.pref_key_connection)
|
|
188 | + )
|
|
186 | 189 | findNavController().navigate(directions)
|
187 | 190 | }
|
188 | 191 |
... | ... | @@ -147,7 +147,7 @@ class TorConnectionAssistFragment : Fragment() { |
147 | 147 | getString(R.string.connection_assist_configure_connection_button)
|
148 | 148 | binding.torBootstrapButton2.setOnClickListener {
|
149 | 149 | viewModel.cancelTorBootstrap()
|
150 | - openTorNetworkSettings()
|
|
150 | + openTorConnectionSettings()
|
|
151 | 151 | }
|
152 | 152 | }
|
153 | 153 | |
... | ... | @@ -235,7 +235,7 @@ class TorConnectionAssistFragment : Fragment() { |
235 | 235 | binding.torBootstrapButton2.text =
|
236 | 236 | getString(R.string.connection_assist_configure_connection_button)
|
237 | 237 | binding.torBootstrapButton2.setOnClickListener {
|
238 | - openTorNetworkSettings()
|
|
238 | + openTorConnectionSettings()
|
|
239 | 239 | }
|
240 | 240 | }
|
241 | 241 | |
... | ... | @@ -376,9 +376,11 @@ class TorConnectionAssistFragment : Fragment() { |
376 | 376 | )
|
377 | 377 | }
|
378 | 378 | |
379 | - private fun openTorNetworkSettings() {
|
|
379 | + private fun openTorConnectionSettings() {
|
|
380 | 380 | findNavController().navigate(
|
381 | - TorConnectionAssistFragmentDirections.actionTorConnectionAssistFragmentToTorNetworkSettings(),
|
|
381 | + TorConnectionAssistFragmentDirections.actionTorConnectionAssistFragmentToSettingsFragment(
|
|
382 | + requireContext().getString(R.string.pref_key_connection)
|
|
383 | + ),
|
|
382 | 384 | )
|
383 | 385 | }
|
384 | 386 | } |
... | ... | @@ -17,6 +17,10 @@ class TorError( |
17 | 17 | var details: String
|
18 | 18 | ) { }
|
19 | 19 | |
20 | +interface TorLogs {
|
|
21 | + fun onLog(type: String?, message: String?)
|
|
22 | +}
|
|
23 | + |
|
20 | 24 | internal enum class TorStatus(val status: String) {
|
21 | 25 | OFF("OFF"),
|
22 | 26 | STARTING("STARTING"),
|
... | ... | @@ -68,6 +72,9 @@ interface TorController: TorEvents { |
68 | 72 | fun registerTorListener(l: TorEvents)
|
69 | 73 | fun unregisterTorListener(l: TorEvents)
|
70 | 74 | |
75 | + fun registerTorLogListener(l: TorLogs)
|
|
76 | + fun unregisterTorLogListener(l: TorLogs)
|
|
77 | + |
|
71 | 78 | fun initiateTorBootstrap(lifecycleScope: LifecycleCoroutineScope? = null, withDebugLogging: Boolean = false)
|
72 | 79 | fun stopTor()
|
73 | 80 | fun setTorStopped()
|
... | ... | @@ -8,6 +8,7 @@ import mozilla.components.browser.engine.gecko.GeckoEngine |
8 | 8 | import org.mozilla.fenix.ext.components
|
9 | 9 | import org.mozilla.geckoview.TorIntegrationAndroid
|
10 | 10 | import org.mozilla.geckoview.TorIntegrationAndroid.BootstrapStateChangeListener
|
11 | +import org.mozilla.geckoview.TorIntegrationAndroid.TorLogListener
|
|
11 | 12 | import org.mozilla.geckoview.TorSettings
|
12 | 13 | import org.mozilla.geckoview.TorSettings.BridgeBuiltinType
|
13 | 14 | import org.mozilla.geckoview.TorSettings.BridgeSource
|
... | ... | @@ -46,11 +47,12 @@ internal enum class TorConnectState(val state: String) { |
46 | 47 | |
47 | 48 | class TorControllerGV(
|
48 | 49 | private val context: Context,
|
49 | -) : TorController, TorEvents, BootstrapStateChangeListener {
|
|
50 | +) : TorController, TorEvents, BootstrapStateChangeListener, TorLogListener {
|
|
50 | 51 | |
51 | 52 | private val TAG = "TorControllerGV"
|
52 | 53 | |
53 | 54 | private var torListeners = mutableListOf<TorEvents>()
|
55 | + private var torLogListeners = mutableListOf<TorLogs>()
|
|
54 | 56 | |
55 | 57 | internal var lastKnownStatus = TorConnectState.Initial
|
56 | 58 | internal var lastKnownError: TorError? = null
|
... | ... | @@ -146,10 +148,12 @@ class TorControllerGV( |
146 | 148 | |
147 | 149 | override fun start() {
|
148 | 150 | getTorIntegration().registerBootstrapStateChangeListener(this)
|
151 | + getTorIntegration().registerLogListener(this)
|
|
149 | 152 | }
|
150 | 153 | |
151 | 154 | override fun stop() {
|
152 | 155 | getTorIntegration().unregisterBootstrapStateChangeListener(this)
|
156 | + getTorIntegration().unregisterLogListener(this)
|
|
153 | 157 | }
|
154 | 158 | |
155 | 159 | // TorEvents
|
... | ... | @@ -180,6 +184,13 @@ class TorControllerGV( |
180 | 184 | }
|
181 | 185 | }
|
182 | 186 | |
187 | + override fun onLog(type: String?, message: String?) {
|
|
188 | + synchronized(torLogListeners) {
|
|
189 | + entries.add(Pair(type, message))
|
|
190 | + torLogListeners.toList().forEach { it.onLog(type, message) }
|
|
191 | + }
|
|
192 | + }
|
|
193 | + |
|
183 | 194 | override fun registerTorListener(l: TorEvents) {
|
184 | 195 | synchronized(torListeners) {
|
185 | 196 | if (torListeners.contains(l)) {
|
... | ... | @@ -198,6 +209,23 @@ class TorControllerGV( |
198 | 209 | }
|
199 | 210 | }
|
200 | 211 | |
212 | + override fun registerTorLogListener(l: TorLogs) {
|
|
213 | + synchronized(torLogListeners) {
|
|
214 | + if (torLogListeners.contains(l)) {
|
|
215 | + return
|
|
216 | + }
|
|
217 | + torLogListeners.add(l)
|
|
218 | + }
|
|
219 | + }
|
|
220 | + override fun unregisterTorLogListener(l: TorLogs) {
|
|
221 | + synchronized(torLogListeners) {
|
|
222 | + if (!torLogListeners.contains(l)) {
|
|
223 | + return
|
|
224 | + }
|
|
225 | + torLogListeners.remove(l)
|
|
226 | + }
|
|
227 | + }
|
|
228 | + |
|
201 | 229 | override fun initiateTorBootstrap(
|
202 | 230 | lifecycleScope: LifecycleCoroutineScope?,
|
203 | 231 | withDebugLogging: Boolean,
|
... | ... | @@ -284,7 +312,6 @@ class TorControllerGV( |
284 | 312 | onTorConnecting()
|
285 | 313 | |
286 | 314 | }
|
287 | - entries.add(Pair(status, lastKnownStatus.toTorStatus().status))
|
|
288 | 315 | onTorStatusUpdate(status, lastKnownStatus.toTorStatus().status, progress)
|
289 | 316 | }
|
290 | 317 |
... | ... | @@ -211,6 +211,9 @@ class TorControllerTAS (private val context: Context): TorController { |
211 | 211 | }
|
212 | 212 | }
|
213 | 213 | |
214 | + override fun registerTorLogListener(l: TorLogs) {}
|
|
215 | + override fun unregisterTorLogListener(l: TorLogs) {}
|
|
216 | + |
|
214 | 217 | private fun handlePendingRegistrationChanges() {
|
215 | 218 | pendingRegisterChangeList.forEach {
|
216 | 219 | if (it.second) {
|
1 | +package org.mozilla.fenix.tor
|
|
2 | + |
|
3 | +import android.os.Bundle
|
|
4 | +import android.text.method.ScrollingMovementMethod
|
|
5 | +import android.view.LayoutInflater
|
|
6 | +import android.view.View
|
|
7 | +import android.view.ViewGroup
|
|
8 | +import androidx.fragment.app.Fragment
|
|
9 | +import org.mozilla.fenix.R
|
|
10 | +import org.mozilla.fenix.components.Components
|
|
11 | +import org.mozilla.fenix.databinding.FragmentHomeBinding
|
|
12 | +import org.mozilla.fenix.databinding.FragmentTorConnectionAssistBinding
|
|
13 | +import org.mozilla.fenix.databinding.TorBootstrapLoggerBinding
|
|
14 | +import org.mozilla.fenix.databinding.TorNetworkSettingsBetaConnectionFeaturesBinding
|
|
15 | +import org.mozilla.fenix.ext.components
|
|
16 | +import org.mozilla.fenix.ext.requireComponents
|
|
17 | +import org.mozilla.fenix.tor.view.TorBootstrapLoggerViewHolder
|
|
18 | + |
|
19 | +class TorLogsFragment(): Fragment(), TorLogs {
|
|
20 | + |
|
21 | + private var entries = mutableListOf<String>()
|
|
22 | + internal var _binding: TorBootstrapLoggerBinding? = null
|
|
23 | + private val binding get() = _binding!!
|
|
24 | + |
|
25 | + private var _components: Components? = null
|
|
26 | + private val components get() = _components!!
|
|
27 | + |
|
28 | + override fun onCreateView(
|
|
29 | + inflater: LayoutInflater,
|
|
30 | + container: ViewGroup?,
|
|
31 | + savedInstanceState: Bundle?,
|
|
32 | + ): View {
|
|
33 | + _binding = TorBootstrapLoggerBinding.inflate(inflater)
|
|
34 | + _components = requireComponents
|
|
35 | + |
|
36 | + components.torController.registerTorLogListener(this)
|
|
37 | + |
|
38 | + val currentEntries = components.torController.logEntries
|
|
39 | + .filter { it.second != null }
|
|
40 | + .filter { !(it.second!!.startsWith("Circuit") && it.first == "ON") }
|
|
41 | + // Keep synchronized with format in onTorStatusUpdate
|
|
42 | + .flatMap { listOf("(${it.first}) '${it.second}'") }
|
|
43 | + val entriesLen = currentEntries.size
|
|
44 | + val subListOffset = if (entriesLen > TorBootstrapLoggerViewHolder.MAX_NEW_ENTRIES) TorBootstrapLoggerViewHolder.MAX_NEW_ENTRIES else entriesLen
|
|
45 | + entries = currentEntries.subList((entriesLen - subListOffset), entriesLen) as MutableList<String>
|
|
46 | + val initLog = "---------------" + getString(R.string.tor_initializing_log) + "---------------"
|
|
47 | + entries.add(0, initLog)
|
|
48 | + |
|
49 | + with(binding.torBootstrapLogEntries) {
|
|
50 | + movementMethod = ScrollingMovementMethod()
|
|
51 | + text = formatLogEntries(entries)
|
|
52 | + }
|
|
53 | + |
|
54 | + |
|
55 | + return binding.root
|
|
56 | + }
|
|
57 | + |
|
58 | + // TODO on destroy unregiuster
|
|
59 | + |
|
60 | + private fun formatLogEntries(entries: List<String>) = entries.joinToString("\n")
|
|
61 | + |
|
62 | + override fun onLog(type: String?, message: String?) {
|
|
63 | + if (message == null || type == null) return
|
|
64 | + if (type == "ON" && type.startsWith("Circuit")) return
|
|
65 | + |
|
66 | + if (entries.size > TorBootstrapLoggerViewHolder.MAX_LINES) {
|
|
67 | + entries = entries.drop(1) as MutableList<String>
|
|
68 | + }
|
|
69 | + entries.add("($type) '$message'")
|
|
70 | + |
|
71 | + binding.torBootstrapLogEntries.text = formatLogEntries(entries)
|
|
72 | + }
|
|
73 | + |
|
74 | + override fun onStop() {
|
|
75 | + super.onStop()
|
|
76 | + components.torController.unregisterTorLogListener(this)
|
|
77 | + }
|
|
78 | + |
|
79 | +} |
... | ... | @@ -239,13 +239,6 @@ |
239 | 239 | android:name="scrollToCollection"
|
240 | 240 | android:defaultValue="false"
|
241 | 241 | app:argType="boolean" />
|
242 | - <action
|
|
243 | - android:id="@+id/action_homeFragment_to_torNetworkSettingsFragment"
|
|
244 | - app:destination="@id/torNetworkSettingsFragment"
|
|
245 | - app:enterAnim="@anim/slide_in_right"
|
|
246 | - app:exitAnim="@anim/slide_out_left"
|
|
247 | - app:popEnterAnim="@anim/slide_in_left"
|
|
248 | - app:popExitAnim="@anim/slide_out_right" />
|
|
249 | 242 | </fragment>
|
250 | 243 | |
251 | 244 | <fragment
|
... | ... | @@ -269,12 +262,13 @@ |
269 | 262 | app:popUpTo="@id/torbootstrapFragment"
|
270 | 263 | app:popUpToInclusive="true" />
|
271 | 264 | <action
|
272 | - android:id="@+id/action_torbootstrapFragment_to_torNetworkSettingsFragment"
|
|
273 | - app:destination="@id/torNetworkSettingsFragment"
|
|
265 | + android:id="@+id/action_torbootstrapFragment_to_SettingsFragment"
|
|
266 | + app:destination="@id/settingsFragment"
|
|
274 | 267 | app:enterAnim="@anim/slide_in_right"
|
275 | 268 | app:exitAnim="@anim/slide_out_left"
|
276 | 269 | app:popEnterAnim="@anim/slide_in_left"
|
277 | 270 | app:popExitAnim="@anim/slide_out_right" />
|
271 | + |
|
278 | 272 | </fragment>
|
279 | 273 | |
280 | 274 | <fragment
|
... | ... | @@ -294,8 +288,8 @@ |
294 | 288 | app:popEnterAnim="@anim/slide_in_left"
|
295 | 289 | app:popExitAnim="@anim/slide_out_right" />
|
296 | 290 | <action
|
297 | - android:id="@+id/action_torConnectionAssistFragment_to_TorNetworkSettings"
|
|
298 | - app:destination="@id/torNetworkSettingsFragment"
|
|
291 | + android:id="@+id/action_torConnectionAssistFragment_to_TorConnectionSettings"
|
|
292 | + app:destination="@id/settingsFragment"
|
|
299 | 293 | app:enterAnim="@anim/slide_in_right"
|
300 | 294 | app:exitAnim="@anim/slide_out_left"
|
301 | 295 | app:popEnterAnim="@anim/slide_in_left"
|
... | ... | @@ -702,8 +696,22 @@ |
702 | 696 | app:popEnterAnim="@anim/slide_in_left"
|
703 | 697 | app:popExitAnim="@anim/slide_out_right" />
|
704 | 698 | <action
|
705 | - android:id="@+id/action_settingsFragment_to_torNetworkSettingsFragment"
|
|
706 | - app:destination="@id/torNetworkSettingsFragment"
|
|
699 | + android:id="@+id/action_settingsFragment_to_torBridgeConfigFragment"
|
|
700 | + app:destination="@id/torBridgeConfigFragment"
|
|
701 | + app:enterAnim="@anim/slide_in_right"
|
|
702 | + app:exitAnim="@anim/slide_out_left"
|
|
703 | + app:popEnterAnim="@anim/slide_in_left"
|
|
704 | + app:popExitAnim="@anim/slide_out_right" />
|
|
705 | + <action
|
|
706 | + android:id="@+id/action_settingsFragment_to_torLogsFragment"
|
|
707 | + app:destination="@+id/torLogsFragment"
|
|
708 | + app:enterAnim="@anim/slide_in_right"
|
|
709 | + app:exitAnim="@anim/slide_out_left"
|
|
710 | + app:popEnterAnim="@anim/slide_in_left"
|
|
711 | + app:popExitAnim="@anim/slide_out_right" />
|
|
712 | + <action
|
|
713 | + android:id="@+id/action_settingsFragment_to_BetaConnectionFeaturesFragment"
|
|
714 | + app:destination="@+id/torBetaConnectionFeaturesFragment"
|
|
707 | 715 | app:enterAnim="@anim/slide_in_right"
|
708 | 716 | app:exitAnim="@anim/slide_out_left"
|
709 | 717 | app:popEnterAnim="@anim/slide_in_left"
|
... | ... | @@ -965,24 +973,6 @@ |
965 | 973 | android:id="@+id/sponsoredStoriesSettings"
|
966 | 974 | android:name="org.mozilla.fenix.settings.SponsoredStoriesSettingsFragment"
|
967 | 975 | android:label="@string/preferences_debug_settings_custom_sponsored_stories_parameters" />
|
968 | - <fragment
|
|
969 | - android:id="@+id/torNetworkSettingsFragment"
|
|
970 | - android:name="org.mozilla.fenix.settings.TorNetworkSettingsFragment">
|
|
971 | - <action
|
|
972 | - android:id="@+id/action_torNetworkSettingsFragment_to_torBridgeConfigFragment"
|
|
973 | - app:destination="@id/torBridgeConfigFragment"
|
|
974 | - app:enterAnim="@anim/slide_in_right"
|
|
975 | - app:exitAnim="@anim/slide_out_left"
|
|
976 | - app:popEnterAnim="@anim/slide_in_left"
|
|
977 | - app:popExitAnim="@anim/slide_out_right" />
|
|
978 | - <action
|
|
979 | - android:id="@+id/action_torNetworkSettingsFragment_to_BetaConnectionFeaturesFragment"
|
|
980 | - app:destination="@+id/torBetaConnectionFeaturesFragment"
|
|
981 | - app:enterAnim="@anim/slide_in_right"
|
|
982 | - app:exitAnim="@anim/slide_out_left"
|
|
983 | - app:popEnterAnim="@anim/slide_in_left"
|
|
984 | - app:popExitAnim="@anim/slide_out_right" />
|
|
985 | - </fragment>
|
|
986 | 976 | <fragment
|
987 | 977 | android:id="@+id/torBridgeConfigFragment"
|
988 | 978 | android:name="org.mozilla.fenix.settings.TorBridgeConfigFragment"
|
... | ... | @@ -993,6 +983,11 @@ |
993 | 983 | android:name="org.mozilla.fenix.tor.TorBetaConnectionFeaturesFragment"
|
994 | 984 | android:label="Enable beta connection features"
|
995 | 985 | tools:layout="@layout/tor_network_settings_beta_connection_features" />
|
986 | + <fragment
|
|
987 | + android:id="@+id/torLogsFragment"
|
|
988 | + android:name="org.mozilla.fenix.tor.TorLogsFragment"
|
|
989 | + android:label="Tor Logs"
|
|
990 | + tools:layout="@layout/tor_bootstrap_logger" />
|
|
996 | 991 | |
997 | 992 | <fragment
|
998 | 993 | android:id="@+id/trackingProtectionFragment"
|
... | ... | @@ -14,6 +14,8 @@ |
14 | 14 | <string name="pref_key_accessibility" translatable="false">pref_key_accessibility</string>
|
15 | 15 | <string name="pref_key_accessibility_auto_size" translatable="false">pref_key_accessibility_auto_size</string>
|
16 | 16 | <string name="pref_key_accessibility_font_scale" translatable="false">pref_key_accessibility_font_scale</string>
|
17 | + <string name="pref_key_privacy" translatable="false">pref_key_privacy</string>
|
|
18 | + <string name="pref_key_connection" translatable="false">pref_key_connection</string>
|
|
17 | 19 | <string name="pref_key_accessibility_force_enable_zoom" translatable="false">pref_key_accessibility_force_enable_zoom</string>
|
18 | 20 | <string name="pref_key_advanced" translatable="false">pref_key_advanced</string>
|
19 | 21 | <string name="pref_key_language" translatable="false">pref_key_language</string>
|
... | ... | @@ -373,10 +375,10 @@ |
373 | 375 | <string name="pref_key_tor_security_level_safer_option" translatable="false">pref_key_tor_security_level_safer_option</string>
|
374 | 376 | <string name="pref_key_tor_security_level_safest_option" translatable="false">pref_key_tor_security_level_safest_option</string>
|
375 | 377 | |
376 | - <string name="pref_key_tor_network_settings" translatable="false">pref_key_tor_network_settings</string>
|
|
377 | 378 | <string name="pref_key_tor_network_settings_explanation" translatable="false">pref_key_tor_network_settings_explanation</string>
|
378 | 379 | <string name="pref_key_tor_network_settings_bridge_config" translatable="false">pref_key_tor_network_settings_bridge_config</string>
|
379 | 380 | <string name="pref_key_use_new_bootstrap" translatable="false">pref_key_use_new_bootstrap</string>
|
381 | + <string name="pref_key_tor_logs" translatable="false">pref_key_tor_logs</string>
|
|
380 | 382 | <string name="pref_key_use_new_bootstrap_with_android_native" translatable="false">pref_key_use_new_bootstrap_with_android_native</string>
|
381 | 383 | <string name="pref_key_use_new_bootstrap_with_html" translatable="false">pref_key_use_new_bootstrap_with_html</string>
|
382 | 384 | <string name="pref_key_tor_network_settings_bridge_config_explanation" translatable="false">pref_key_tor_network_settings_bridge_config_explanation</string>
|
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | |
32 | 32 | <string name="tor_explore_privately">Explore. Privately.</string>
|
33 | 33 | |
34 | + <string name="preferences_tor_connection_settings_title">Connection</string>
|
|
34 | 35 | <string name="preferences_tor_network_settings">Tor Network</string>
|
35 | 36 | <string name="preferences_tor_network_settings_explanation">Tor Browser routes your traffic over the Tor Network, run by thousands of volunteers around the world.</string>
|
36 | 37 | <string name="preferences_tor_network_settings_bridge_config">Config Bridge</string>
|
... | ... | @@ -57,6 +58,8 @@ |
57 | 58 | <string name="preferences_tor_network_settings_connected">Connected</string>
|
58 | 59 | <string name="preferences_tor_network_settings_restarting">Restarting</string>
|
59 | 60 | <string name="preferences_tor_network_settings_bridges_enabled">Bridges are enabled: %s</string>
|
61 | + <string name="preferences_tor_logs">Tor Logs</string>
|
|
62 | + <string name="preferences_tor_logs_description">View and copy your Tor logs</string>
|
|
60 | 63 | |
61 | 64 | <!-- Preference title for security level settings -->
|
62 | 65 | <string name="preferences_tor_security_level_settings">Security Settings</string>
|
... | ... | @@ -93,6 +93,7 @@ |
93 | 93 | |
94 | 94 | <androidx.preference.PreferenceCategory
|
95 | 95 | android:title="@string/preferences_category_privacy_security"
|
96 | + android:key="@string/pref_key_privacy"
|
|
96 | 97 | android:layout="@layout/preference_category_no_icon_style">
|
97 | 98 | |
98 | 99 | <androidx.preference.Preference
|
... | ... | @@ -117,11 +118,6 @@ |
117 | 118 | android:title="@string/preferences_cookie_banner_reduction"
|
118 | 119 | app:isPreferenceVisible="false" />
|
119 | 120 | |
120 | - <androidx.preference.Preference
|
|
121 | - android:key="@string/pref_key_tor_network_settings"
|
|
122 | - app:iconSpaceReserved="false"
|
|
123 | - android:title="@string/preferences_tor_network_settings" />
|
|
124 | - |
|
125 | 121 | <androidx.preference.Preference
|
126 | 122 | android:key="@string/pref_key_tracking_protection_settings"
|
127 | 123 | app:iconSpaceReserved="false"
|
... | ... | @@ -156,6 +152,41 @@ |
156 | 152 | |
157 | 153 | </androidx.preference.PreferenceCategory>
|
158 | 154 | |
155 | + <!-- title="@string/preferences_category_advanced"
|
|
156 | + key="@string/pref_key_advanced"-->
|
|
157 | + <PreferenceCategory
|
|
158 | + android:title="@string/preferences_tor_connection_settings_title"
|
|
159 | + android:key="@string/pref_key_connection"
|
|
160 | + android:layout="@layout/preference_category_no_icon_style">
|
|
161 | + |
|
162 | + <Preference
|
|
163 | + android:key="@string/pref_key_tor_network_settings_explanation"
|
|
164 | + app:iconSpaceReserved="false"
|
|
165 | + android:title="@string/preferences_tor_network_settings_explanation" />
|
|
166 | + |
|
167 | + <Preference
|
|
168 | + android:key="@string/pref_key_tor_network_settings_bridge_config"
|
|
169 | + app:iconSpaceReserved="false"
|
|
170 | + android:title="@string/preferences_tor_network_settings_bridge_config"
|
|
171 | + android:summary="@string/preferences_tor_network_settings_bridge_config_description" />
|
|
172 | + |
|
173 | + <Preference
|
|
174 | + android:key="@string/pref_key_use_new_bootstrap"
|
|
175 | + app:iconSpaceReserved="false"
|
|
176 | + android:title="Enable beta connection features" />
|
|
177 | + |
|
178 | + <Preference
|
|
179 | + android:key="@string/pref_key_tor_logs"
|
|
180 | + app:iconSpaceReserved="false"
|
|
181 | + android:title="@string/preferences_tor_logs"
|
|
182 | + android:summary="@string/preferences_tor_logs_description" />
|
|
183 | + |
|
184 | + <!-- Auto connect -->
|
|
185 | + |
|
186 | + <!-- Tor Logs -->
|
|
187 | + |
|
188 | + </PreferenceCategory>
|
|
189 | + |
|
159 | 190 | <PreferenceCategory
|
160 | 191 | android:title="@string/preferences_category_advanced"
|
161 | 192 | android:key="@string/pref_key_advanced"
|
1 | -<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
|
|
2 | - - License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3 | - - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
|
4 | -<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
|
5 | - xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
6 | - <Preference
|
|
7 | - android:key="@string/pref_key_tor_network_settings_explanation"
|
|
8 | - android:title="@string/preferences_tor_network_settings_explanation" />
|
|
9 | - <androidx.preference.PreferenceCategory
|
|
10 | - android:key="@string/pref_key_tor_network_settings_status"
|
|
11 | - android:title="@string/preferences_tor_network_settings_status"
|
|
12 | - app:iconSpaceReserved="false"
|
|
13 | - android:layout="@layout/preference_cat_style" >
|
|
14 | - <Preference
|
|
15 | - android:key="@string/pref_key_tor_network_settings_tor_ready"
|
|
16 | - android:title="@string/preferences_tor_network_settings_tor_ready" />
|
|
17 | - <Preference
|
|
18 | - android:key="@string/pref_key_tor_network_settings_state"
|
|
19 | - android:title="@string/preferences_tor_network_settings_state" />
|
|
20 | - <Preference
|
|
21 | - android:key="@string/pref_key_tor_network_settings_bridges_enabled"
|
|
22 | - android:title="@string/preferences_tor_network_settings_bridges_enabled" />
|
|
23 | - </androidx.preference.PreferenceCategory>
|
|
24 | - <Preference
|
|
25 | - android:icon="@drawable/ic_tor_config_bridge"
|
|
26 | - android:key="@string/pref_key_tor_network_settings_bridge_config"
|
|
27 | - android:title="@string/preferences_tor_network_settings_bridge_config"
|
|
28 | - android:summary="@string/preferences_tor_network_settings_bridge_config_description"
|
|
29 | - app:allowDividerAbove="true" />
|
|
30 | - <Preference
|
|
31 | - android:key="@string/pref_key_use_new_bootstrap"
|
|
32 | - android:title="Enable beta connection features"
|
|
33 | - app:allowDividerAbove="true" />
|
|
34 | - |
|
35 | -</androidx.preference.PreferenceScreen> |