Commits:
9 changed files:
Changes:
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
| ... |
... |
@@ -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
|
} |
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
| ... |
... |
@@ -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,
|
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
| ... |
... |
@@ -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
|
} |
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt
| ... |
... |
@@ -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) {
|
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.kt
| ... |
... |
@@ -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
|
} |
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerGV.kt
| ... |
... |
@@ -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?) {
|
mobile/android/fenix/app/src/main/res/layout/fenix_snackbar.xml
| ... |
... |
@@ -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"
|
mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml
| ... |
... |
@@ -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"
|
mobile/android/fenix/app/src/main/res/values/torbrowser_strings.xml
| ... |
... |
@@ -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> |
|