Pier Angelo Vendrame pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android
Commits: 6c3669ee by clairehurst at 2024-02-21T18:55:49-07:00 fixup! Modify build system
- - - - - cd3473f6 by clairehurst at 2024-02-21T20:41:44-07:00 fixup! Add Tor integration and UI
Remove quick start
- - - - - 5e60c209 by clairehurst at 2024-02-21T21:10:03-07:00 Implement Android-native Connection Assist UI
- - - - - 7c1cc539 by clairehurst at 2024-02-21T21:10:03-07:00 fixup! Enable the connect assist experiments on alpha
- - - - -
22 changed files:
- fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt - fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt - fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/tor/TorBetaConnectionFeaturesFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt - + fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt - + fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.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/bootstrap/TorQuickStart.kt - fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt - + fenix/app/src/main/res/drawable/connect.xml - fenix/app/src/main/res/drawable/progress_gradient.xml - + fenix/app/src/main/res/layout/fragment_tor_connection_assist.xml - fenix/app/src/main/res/layout/tor_bootstrap_connect.xml - fenix/app/src/main/res/layout/tor_network_settings_beta_connection_features.xml - fenix/app/src/main/res/navigation/nav_graph.xml - fenix/app/src/main/res/values/colors.xml - fenix/app/src/main/res/values/torbrowser_strings.xml - fenix/tools/tba-fetch-deps.sh
Changes:
===================================== fenix/app/src/main/java/org/mozilla/fenix/BrowserDirection.kt ===================================== @@ -41,4 +41,5 @@ enum class BrowserDirection(@IdRes val fragmentId: Int) { FromLoginDetailFragment(R.id.loginDetailFragment), FromTabsTray(R.id.tabsTrayFragment), FromRecentlyClosed(R.id.recentlyClosedFragment), + FromTorConnectionAssistFragment(R.id.torConnectionAssistFragment) }
===================================== fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt ===================================== @@ -157,6 +157,7 @@ import org.mozilla.fenix.tabstray.TabsTrayFragment import org.mozilla.fenix.tabstray.TabsTrayFragmentDirections import org.mozilla.fenix.theme.DefaultThemeManager import org.mozilla.fenix.theme.ThemeManager +import org.mozilla.fenix.tor.TorConnectionAssistFragmentDirections import org.mozilla.fenix.tor.TorEvents import org.mozilla.fenix.trackingprotection.TrackingProtectionPanelDialogFragmentDirections import org.mozilla.fenix.utils.BrowsersCache @@ -1085,6 +1086,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn BrowserDirection.FromStudiesFragment -> StudiesFragmentDirections.actionGlobalBrowser( customTabSessionId, ) + BrowserDirection.FromTorConnectionAssistFragment, + -> TorConnectionAssistFragmentDirections.actionGlobalBrowser( + customTabSessionId, + ) }
/**
===================================== fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt ===================================== @@ -115,7 +115,6 @@ import org.mozilla.fenix.search.toolbar.SearchSelectorMenu import org.mozilla.fenix.tabstray.TabsTrayAccessPoint import org.mozilla.fenix.tor.TorBootstrapFragmentDirections import org.mozilla.fenix.tor.TorBootstrapStatus -import org.mozilla.fenix.tor.bootstrap.TorQuickStart import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.wallpapers.Wallpaper @@ -202,7 +201,6 @@ class HomeFragment : Fragment() { private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>() private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>() private val searchSelectorBinding = ViewBoundFeatureWrapper<SearchSelectorBinding>() - private val torQuickStart by lazy { TorQuickStart(requireContext()) } private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>() private lateinit var torBootstrapStatus: TorBootstrapStatus
@@ -236,7 +234,6 @@ class HomeFragment : Fragment() { val components = requireComponents
torBootstrapStatus = TorBootstrapStatus( - torQuickStart, !BuildConfig.DISABLE_TOR, components.torController, ::dispatchModeChanges
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorBetaConnectionFeaturesFragment.kt ===================================== @@ -54,10 +54,7 @@ class TorBetaConnectionFeaturesFragment : Fragment() { children.forEach { it.isEnabled = false } } } else { - // Do not enable the native UI until it is actually available. - // binding.enableBetaConnectionFeaturesModes.children.forEach { it.isEnabled = true } - binding.useNewBootstrapWithHtmlUiRadioButton.isEnabled = true - binding.useNewBootstrapWithNativeUiRadioButton.isEnabled = false + binding.enableBetaConnectionFeaturesModes.children.forEach { it.isEnabled = true } } }
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt ===================================== @@ -8,14 +8,12 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.annotation.VisibleForTesting import androidx.core.view.children import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.databinding.FragmentHomeBinding import org.mozilla.fenix.ext.requireComponents -import org.mozilla.fenix.tor.bootstrap.TorQuickStart import org.mozilla.fenix.tor.interactor.DefaultTorBootstrapInteractor import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor import androidx.navigation.fragment.findNavController @@ -30,7 +28,6 @@ import org.mozilla.fenix.tor.view.TorBootstrapView
@Suppress("TooManyFunctions", "LargeClass") class TorBootstrapFragment : Fragment() { - private val torQuickStart by lazy { TorQuickStart(requireContext()) }
internal var _binding: FragmentHomeBinding? = null private val binding get() = _binding!! @@ -55,7 +52,6 @@ class TorBootstrapFragment : Fragment() { val components = requireComponents
torBootstrapStatus = TorBootstrapStatus( - torQuickStart, !BuildConfig.DISABLE_TOR, components.torController, ::dispatchModeChanges
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt ===================================== @@ -4,11 +4,8 @@
package org.mozilla.fenix.tor
-import org.mozilla.fenix.tor.bootstrap.TorQuickStart - @SuppressWarnings("LongParameterList", "TooManyFunctions") class TorBootstrapStatus( - private val torQuickStart: TorQuickStart, private val shouldStartTor: Boolean, private val torController: TorController, private val dispatchModeChanges: (isShouldBootstrap: Boolean) -> Unit @@ -18,7 +15,7 @@ class TorBootstrapStatus( torController.registerTorListener(this) }
- fun isBootstrapping() = (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped)) + fun isBootstrapping() = (shouldStartTor && !torController.isBootstrapped)
@SuppressWarnings("EmptyFunctionBlock")
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt ===================================== @@ -0,0 +1,131 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.tor + +import android.os.Build +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.navigation.fragment.findNavController +import kotlinx.coroutines.launch +import org.mozilla.fenix.R +import org.mozilla.fenix.databinding.FragmentTorConnectionAssistBinding +import org.mozilla.fenix.ext.hideToolbar + +class TorConnectionAssistFragment : Fragment() { + + private var _binding: FragmentTorConnectionAssistBinding? = null + private val binding get() = _binding!! + + private val viewModel: TorConnectionAssistViewModel by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + _binding = FragmentTorConnectionAssistBinding.inflate( + inflater, container, false, + ) + + return binding.root + } + + override fun onResume() { + super.onResume() + hideToolbar() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.torConnectState.collect { + when (it) { + TorConnectState.Initial -> showConfiguring() + TorConnectState.Configuring -> showConfiguring() + TorConnectState.AutoBootstrapping -> showBootstrapping() + TorConnectState.Bootstrapping -> showBootstrapping() + TorConnectState.Error -> TODO() + TorConnectState.Bootstrapped -> openHome() + TorConnectState.Disabled -> openHome() + } + } + } + } + + viewModel.progress().observe( + viewLifecycleOwner, + ) { progress -> + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + binding.torBootstrapProgressBar.setProgress(progress, true) + } else { + binding.torBootstrapProgressBar.progress = progress + } + } + + viewModel.quickconnectToggle().observe( + viewLifecycleOwner + ) { + binding.quickstartSwitch.isChecked = it + } + + binding.settingsButton.setOnClickListener { + viewModel.cancelTorBootstrap() + openSettings() + } + + binding.torBootstrapConnectButton.setOnClickListener { + viewModel.handleConnect(lifecycleScope = lifecycleScope) + } + + binding.quickstartSwitch.setOnCheckedChangeListener { _, isChecked -> + viewModel.handleQuickstartChecked(isChecked) + } + } + + private fun showConfiguring() { + binding.torBootstrapConnectButton.visibility = View.VISIBLE + binding.torBootstrapNetworkSettingsButton.text = + getString(R.string.connection_assist_configure_connection_button) + binding.torBootstrapNetworkSettingsButton.setOnClickListener { + openTorNetworkSettings() + } + } + + private fun showBootstrapping() { + binding.torBootstrapConnectButton.visibility = View.INVISIBLE + binding.torBootstrapNetworkSettingsButton.text = getString(R.string.btn_cancel) + binding.torBootstrapNetworkSettingsButton.setOnClickListener { + viewModel.cancelTorBootstrap() + } + } + + private fun openSettings(preferenceToScrollTo: String? = null) { + findNavController().navigate( + TorConnectionAssistFragmentDirections + .actionTorConnectionAssistFragmentToSettingsFragment(preferenceToScrollTo), + ) + } + + private fun openTorNetworkSettings() { + findNavController().navigate( + TorConnectionAssistFragmentDirections + .actionTorConnectionAssistFragmentToTorNetworkSettings(), + ) + } + + private fun openHome() { + findNavController().navigate(TorConnectionAssistFragmentDirections.actionStartupHome()) + } + +}
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.kt ===================================== @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.tor + +import android.app.Application +import android.util.Log +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LifecycleCoroutineScope +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import org.mozilla.fenix.ext.components + +class TorConnectionAssistViewModel( + application: Application, +) : AndroidViewModel(application), TorEvents { + + private val TAG = "torConnectionAssistVM" + private val components = getApplication<Application>().components + + private val _torController: TorControllerGV = components.torController as TorControllerGV + + private val _torConnectState = MutableStateFlow(TorConnectState.Initial) + internal val torConnectState: StateFlow<TorConnectState> = _torConnectState + + init { + _torController.registerTorListener(this) + } + + private val _progress = MutableLiveData(0) + fun progress(): LiveData<Int> { + return _progress + } + + private val _quickconnectToggle = MutableLiveData(_torController.quickstart) + fun quickconnectToggle(): LiveData<Boolean> { + return _quickconnectToggle + } + + fun handleConnect( + withDebugLogging: Boolean = false, + lifecycleScope: LifecycleCoroutineScope? = null, + ) { + _torController.initiateTorBootstrap( + withDebugLogging = withDebugLogging, + lifecycleScope = lifecycleScope, + ) + } + + fun handleQuickstartChecked(checked: Boolean) { + _torController.quickstart = checked + } + + fun cancelTorBootstrap() { + _torController.stopTor() + _torController.setTorStopped() + } + + override fun onTorConnecting() { + Log.d(TAG, "onTorConnecting()") + } + + override fun onTorConnected() { + Log.d(TAG, "onTorConnected()") + _torController.unregisterTorListener(this) + _torConnectState.value = _torController.lastKnownStatus + } + + override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) { + Log.d(TAG, "onTorStatusUpdate($entry, $status, $progress)") + if (progress != null) { + _progress.value = progress.toInt() + } + _torConnectState.value = _torController.lastKnownStatus + } + + override fun onTorStopped() { + Log.d(TAG, "onTorStopped()") + _progress.value = 0 + _torConnectState.value = _torController.lastKnownStatus + } + +}
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorController.kt ===================================== @@ -49,6 +49,7 @@ interface TorController: TorEvents { var bridgesEnabled: Boolean var bridgeTransport: TorBridgeTransportConfig var userProvidedBridges: String? + var quickstart: Boolean
fun start() fun stop()
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerGV.kt ===================================== @@ -52,7 +52,7 @@ class TorControllerGV(
private var torListeners = mutableListOf<TorEvents>()
- private var lastKnownStatus = TorConnectState.Initial + internal var lastKnownStatus = TorConnectState.Initial private var wasTorBootstrapped = false private var isTorRestarting = false
@@ -66,6 +66,17 @@ class TorControllerGV( override val isBootstrapped get() = isTorBootstrapped override val isConnected get() = (lastKnownStatus.isStarted() && !isTorRestarting)
+ override var quickstart: Boolean + get() { + return getTorSettings()?.quickstart ?: false + } + set(value) { + getTorSettings()?.let { + it.quickstart = value + getTorIntegration().setSettings(it, true, true) + } + } + private fun getTorIntegration(): TorIntegrationAndroid { return (context.components.core.engine as GeckoEngine).getTorIntegrationController() } @@ -198,7 +209,7 @@ class TorControllerGV( }
override fun setTorStopped() { - lastKnownStatus = TorConnectState.Disabled + lastKnownStatus = TorConnectState.Configuring onTorStopped() }
@@ -243,7 +254,7 @@ class TorControllerGV( if (isTorRestarting) { initiateTorBootstrap() } else { - onTorStopped() + setTorStopped() } }
@@ -280,6 +291,7 @@ class TorControllerGV( // TorEventsBootstrapStateChangeListener override fun onBootstrapError(message: String?, details: String?) { lastKnownStatus = TorConnectState.Error + onBootstrapStateChange(TorConnectState.Error.state) }
// TorEventsBootstrapStateChangeListener
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerTAS.kt ===================================== @@ -19,6 +19,7 @@ class TorControllerTAS (private val context: Context): TorController { private val lbm: LocalBroadcastManager = LocalBroadcastManager.getInstance(context) private val entries = mutableListOf<Pair<String?, String?>>() override val logEntries get() = entries + override var quickstart: Boolean = false // Stub, is never used
private var torListeners = mutableListOf<TorEvents>()
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/bootstrap/TorQuickStart.kt deleted ===================================== @@ -1,54 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.tor.bootstrap - -import android.content.Context -import android.content.SharedPreferences -import android.os.StrictMode -import androidx.annotation.VisibleForTesting -import mozilla.components.support.ktx.android.content.PreferencesHolder -import mozilla.components.support.ktx.android.content.booleanPreference -import org.mozilla.fenix.ext.components - -class TorQuickStart(val context: Context) : PreferencesHolder { - - override val preferences: SharedPreferences = - context.components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { - context.getSharedPreferences( - PREF_NAME_TOR_BOOTSTRAP_KEY, - Context.MODE_PRIVATE - ) - } - - private var torQuickStart by booleanPreference(TOR_QUICK_START, default = false) - - fun quickStartTor() = - context.components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { torQuickStart } - - fun enableQuickStartTor() { - torQuickStart = true - } - fun disableQuickStartTor() { - torQuickStart = false - } - fun setQuickStartTor(enabled: Boolean) = if (enabled) { - enableQuickStartTor() - } else { - disableQuickStartTor() - } - - companion object { - /** - * Name of the shared preferences file. - */ - private const val PREF_NAME_TOR_BOOTSTRAP_KEY = "tor.bootstrap" - - /** - * Key for [quickStartTor]. - */ - @VisibleForTesting - internal const val TOR_QUICK_START = "tor.bootstrap.quick_start_enabled" - } -}
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt ===================================== @@ -10,7 +10,6 @@ import org.mozilla.fenix.R import org.mozilla.fenix.components.Components import org.mozilla.fenix.databinding.TorBootstrapConnectBinding import org.mozilla.fenix.tor.TorEvents -import org.mozilla.fenix.tor.bootstrap.TorQuickStart import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
class TorBootstrapConnectViewHolder( @@ -23,17 +22,6 @@ class TorBootstrapConnectViewHolder(
init { binding = TorBootstrapConnectBinding.bind(view) - val torQuickStart = TorQuickStart(view.context) - setQuickStartDescription(view, torQuickStart) - - with(binding.quickStartToggle) { - setOnCheckedChangeListener { _, isChecked -> - torQuickStart.setQuickStartTor(isChecked) - setQuickStartDescription(view, torQuickStart) - } - - isChecked = torQuickStart.quickStartTor() - }
with(binding.torBootstrapNetworkSettingsButton) { setOnClickListener { @@ -66,20 +54,6 @@ class TorBootstrapConnectViewHolder( components.torController.registerTorListener(this) }
- private fun setQuickStartDescription(view: View, torQuickStart: TorQuickStart) { - val resources = view.context.resources - val appName = resources.getString(R.string.app_name) - if (torQuickStart.quickStartTor()) { - binding.torBootstrapQuickStartDescription.text = resources.getString( - R.string.tor_bootstrap_quick_start_enabled, appName - ) - } else { - binding.torBootstrapQuickStartDescription.text = resources.getString( - R.string.tor_bootstrap_quick_start_disabled - ) - } - } - @SuppressWarnings("EmptyFunctionBlock") override fun onTorConnecting() { }
===================================== fenix/app/src/main/res/drawable/connect.xml ===================================== @@ -0,0 +1,17 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="40dp" + android:height="40dp" + android:viewportWidth="40" + android:viewportHeight="40"> + <path + android:pathData="M20,1.253C9.647,1.253 1.253,9.647 1.253,20C1.253,28.967 7.547,36.46 15.96,38.307C16.84,38.5 17.733,38.633 18.653,38.693V24.373C16.787,23.8 15.427,22.06 15.427,20C15.427,17.473 17.473,15.427 20,15.427C22.527,15.427 24.573,17.473 24.573,20C24.573,22.06 23.213,23.8 21.347,24.373V38.693C22.267,38.633 23.16,38.5 24.04,38.307C32.453,36.46 38.747,28.967 38.747,20C38.747,9.647 30.353,1.253 20,1.253ZM24.04,35.293V26.32C26.12,24.987 27.5,22.653 27.5,20C27.5,15.86 24.14,12.5 20,12.5C15.86,12.5 12.5,15.86 12.5,20C12.5,22.653 13.88,24.987 15.96,26.32V35.293C9.18,33.513 4.18,27.347 4.18,20C4.18,11.26 11.26,4.18 20,4.18C28.74,4.18 35.82,11.26 35.82,20C35.82,27.347 30.82,33.513 24.04,35.293Z" + android:fillColor="#FBFBFE" + android:fillType="evenOdd"/> + <path + android:pathData="M20,6.873C12.753,6.873 6.873,12.753 6.873,20C6.873,25.84 10.687,30.787 15.96,32.487V29.36C12.34,27.8 9.807,24.193 9.807,20C9.807,14.367 14.367,9.807 20,9.807C25.633,9.807 30.193,14.367 30.193,20C30.193,24.193 27.66,27.8 24.04,29.36V32.487C29.313,30.787 33.127,25.84 33.127,20C33.127,12.753 27.247,6.873 20,6.873Z" + android:fillColor="#FBFBFE" + android:fillType="evenOdd"/> + <path + android:pathData="M20,22.1C21.16,22.1 22.1,21.159 22.1,20C22.1,18.84 21.16,17.9 20,17.9C18.84,17.9 17.9,18.84 17.9,20C17.9,21.159 18.84,22.1 20,22.1Z" + android:fillColor="#FBFBFE"/> +</vector>
===================================== fenix/app/src/main/res/drawable/progress_gradient.xml ===================================== @@ -12,16 +12,10 @@ <item android:id="@android:id/progress"> <scale android:scaleWidth="100%"> <shape> - <corners - android:bottomLeftRadius="0dp" - android:bottomRightRadius="8dp" - android:topLeftRadius="0dp" - android:topRightRadius="8dp"/> <gradient - android:angle="45" - android:centerColor="#F10366" - android:endColor="#FF9100" - android:startColor="#6173FF" /> + android:angle="0" + android:endColor="#00DBDE" + android:startColor="#FC00FF"/> </shape> </scale> </item>
===================================== fenix/app/src/main/res/layout/fragment_tor_connection_assist.xml ===================================== @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/tor_bootstrap_background_gradient"> + + <ProgressBar + android:id="@+id/tor_bootstrap_progress_bar" + style="?android:attr/progressBarStyleHorizontal" + android:layout_width="match_parent" + android:layout_height="6dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/settings_button" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginTop="26dp" + android:layout_marginEnd="20dp" + android:contentDescription="@string/settings" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/mozac_ic_settings" /> + + <ImageView + android:id="@+id/tor_connect_image" + android:layout_width="40dp" + android:layout_height="40dp" + android:layout_marginStart="24dp" + android:contentDescription="@string/tor_bootstrap_connect" + android:visibility="visible" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/tor_bootstrap_progress_bar" + app:layout_constraintVertical_bias="0.075" + app:srcCompat="@drawable/connect" /> + + <TextView + android:id="@+id/title_large_text_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginTop="24dp" + android:layout_marginEnd="24dp" + android:text="@string/connection_assist_tor_connect_title" + android:textColor="#FBFBFE" + android:textFontWeight="400" + android:textSize="22sp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tor_connect_image" /> + + <TextView + android:id="@+id/connect_to_tor_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="24dp" + android:text="@string/preferences_tor_network_settings_explanation" + android:textColor="#FBFBFE" + android:textFontWeight="400" + android:textSize="14sp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/title_large_text_view" /> + + <TextView + android:id="@+id/connect_automatically" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginTop="24dp" + android:text="@string/connection_assist_always_connect_automatically_toggle_description" + android:textColor="#FBFBFE" + android:textSize="14sp" + app:layout_constraintBottom_toBottomOf="@+id/quickstart_switch" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@+id/quickstart_switch" + app:layout_constraintVertical_bias="1.25" /> + + <com.google.android.material.switchmaterial.SwitchMaterial + android:id="@+id/quickstart_switch" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="24dp" + android:layout_marginEnd="24dp" + android:layout_marginBottom="24dp" + android:enabled="false" + android:gravity="center" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/connect_to_tor_description" + app:layout_goneMarginEnd="6dp" + app:layout_goneMarginTop="9dp" /> + + <Button + android:id="@+id/tor_bootstrap_connect_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:layout_marginBottom="8dp" + android:background="@drawable/rounded_corners" + android:backgroundTint="@color/connect_button_purple" + android:maxWidth="312dp" + android:text="@string/tor_bootstrap_connect" + android:textAllCaps="false" + android:textColor="#FBFBFE" + android:textFontWeight="500" + android:textSize="14sp" + android:textStyle="bold" + app:layout_constraintBottom_toTopOf="@id/tor_bootstrap_network_settings_button" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/quickstart_switch" + app:layout_constraintVertical_bias="1" /> + + + <Button + android:id="@+id/tor_bootstrap_network_settings_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:layout_marginBottom="24dp" + android:background="@drawable/rounded_corners" + android:backgroundTint="@color/configure_connection_button_white" + android:maxWidth="312dp" + android:text="@string/connection_assist_configure_connection_button" + android:textAllCaps="false" + android:textColor="#15141A" + android:textFontWeight="500" + android:textSize="14sp" + android:textStyle="bold" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + +</androidx.constraintlayout.widget.ConstraintLayout>
===================================== fenix/app/src/main/res/layout/tor_bootstrap_connect.xml ===================================== @@ -44,42 +44,6 @@ android:layout_height="wrap_content" android:layout_above="@id/tor_bootstrap_connect_button" />
- <TextView - android:id="@+id/quick_start_label" - android:visibility="gone" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="@dimen/library_item_icon_margin_horizontal" - android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal" - android:layout_above="@id/tor_bootstrap_quick_start_description" - android:layout_toEndOf="@id/quick_start_toggle" - android:paddingStart="8dp" - android:paddingEnd="8dp" - android:clickable="false" - android:textAppearance="@style/ListItemTextStyle" - android:textColor="#EEEEEE" - android:text="@string/tor_bootstrap_quick_start_label" - android:textSize="18sp" /> - - <TextView - android:id="@+id/tor_bootstrap_quick_start_description" - android:visibility="gone" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="@dimen/library_item_icon_margin_horizontal" - android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal" - android:paddingStart="8dp" - android:paddingEnd="8dp" - android:clickable="false" - android:layout_marginBottom="20dp" - android:textAppearance="@style/ListItemTextStyle" - android:layout_toEndOf="@id/quick_start_toggle" - android:layout_above="@id/tor_bootstrap_connect_button" - android:textColor="#FFBBBBBB" - android:text="@string/tor_bootstrap_quick_start_disabled" - android:lines="3" - android:textSize="18sp" /> - <Button android:id="@+id/tor_bootstrap_connect_button" android:layout_width="wrap_content"
===================================== fenix/app/src/main/res/layout/tor_network_settings_beta_connection_features.xml ===================================== @@ -84,7 +84,6 @@ android:background="?android:attr/selectableItemBackground" android:button="@null" android:drawablePadding="@dimen/radio_button_preference_drawable_padding" - android:enabled="false" android:paddingStart="@dimen/radio_button_preference_horizontal" android:paddingTop="@dimen/radio_button_preference_vertical" android:paddingEnd="@dimen/radio_button_preference_horizontal"
===================================== fenix/app/src/main/res/navigation/nav_graph.xml ===================================== @@ -277,6 +277,31 @@ app:popExitAnim="@anim/slide_out_right" /> </fragment>
+ <fragment + android:id="@+id/torConnectionAssistFragment" + android:name="org.mozilla.fenix.tor.TorConnectionAssistFragment" + tools:layout="@layout/fragment_home"> + <action + android:id="@+id/action_home" + app:destination="@id/homeFragment" + app:popUpTo="@id/torConnectionAssistFragment" + app:popUpToInclusive="true" /> + <action + android:id="@+id/action_torConnectionAssistFragment_to_SettingsFragment" + app:destination="@id/settingsFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> + <action + android:id="@+id/action_torConnectionAssistFragment_to_TorNetworkSettings" + app:destination="@id/torNetworkSettingsFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> + </fragment> + <dialog android:id="@+id/homeOnboardingDialogFragment" android:name="org.mozilla.fenix.onboarding.HomeOnboardingDialogFragment" /> @@ -769,6 +794,13 @@ app:exitAnim="@anim/slide_out_left" app:popEnterAnim="@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" /> + <action + android:id="@+id/action_settingsFragment_to_TorConnectionAssistFragment" + app:destination="@id/torConnectionAssistFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> </fragment> <dialog android:id="@+id/profilerStartDialogFragment"
===================================== fenix/app/src/main/res/values/colors.xml ===================================== @@ -340,4 +340,9 @@
<!-- Material Design colors --> <color name="material_scrim_color">#52000000</color> + + <!-- Connection Assist --> + <color name="connect_button_purple">#9059FF</color> + <color name="configure_connection_button_white">#E1E0E7</color> + </resources>
===================================== fenix/app/src/main/res/values/torbrowser_strings.xml ===================================== @@ -75,4 +75,73 @@ <!-- Onion location --> <string name="preferences_tor_prioritize_onions">Prioritize .onion sites</string>
+ <!-- Connection assist. --> + <string name="connection_assist_tor_connect_title">Connect to Tor</string> + <!-- Connection assist. --> + <string name="connection_assist_always_connect_automatically_toggle_description">Always connect automatically</string> + <!-- Connection assist. --> + <string name="connection_assist_configure_connection_button">Configure connection…</string> + + <!-- Connection assist. --> + <string name="connection_assist_connecting_title">Establishing a connection…</string> + + <!-- Connection assist. --> + <string name="connection_assist_internet_error_title">We can’t reach the internet</string> + <!-- Connection assist. %1$s is connection_assist_internet_error_learn_more--> + <string name="connection_assist_internet_error_description">This could be due to a connection issue rather than Tor being blocked. Check your internet connection, proxy, and firewall settings before trying again. %1$s</string> + <!-- Connection assist. --> + <string name="connection_assist_internet_error_learn_more">Learn more</string> + <!-- Connection assist. --> + <string name="connection_assist_internet_error_try_again">Try again</string> + + <!-- Connection assist. --> + <string name="connection_assist_trying_again_waiting_title">Trying again…</string> + + <!-- Connection assist. --> + <string name="connection_assist_cant_connect_to_tor_title">We can’t connect to Tor directly</string> + <!-- Connection assist. %1$s is connection_assist_try_a_bridge_learn_more--> + <string name="connection_assist_try_a_bridge_description">Try connecting via a bridge instead. By providing your location, we can look up the bridge that’s most likely to unblock the internet in your country or region. %1$s</string> + <!-- Connection assist. --> + <string name="connection_assist_unblock_the_internet_in_country_or_region">Unblock the internet in:</string> + <!-- Connection assist. --> + <string name="connection_assist_share_my_location_country_or_region">Share my location</string> + <!-- Connection assist. --> + <string name="connection_assist_try_a_bridge_button">Try a bridge</string> + + <!-- Connection assist. %1$s is connection_assist_choose_a_bridge_manually_link--> + <string name="connection_assist_try_a_bridge_learn_more_description1">Tor Browser will need to establish a brief non-Tor connection to determine your location and look up a bridge. If you don’t want to do that, you can %1$s instead.</string> + <!-- Connection assist. --> + <string name="connection_assist_choose_a_bridge_manually_link">choose a bridge manually</string> + <!-- Connection assist. %s is the error code--> + <string name="connection_assist_try_a_bridge_learn_more_error_code">Error code: %s</string> + + <!-- Connection assist. --> + <string name="connection_assist_trying_a_bridge_title">Trying a bridge…</string> + + <!-- Connection assist. --> + <string name="connection_assist_location_error_title">We couldn’t find your location</string> + <!-- Connection assist. %1$s is connection_assist_find_bridge_location_description, %2$s is connection_assist_select_country_try_again, %3$s is connection_assist_location_error_learn_more_link--> + <string name="connection_assist_location_error_description" translatable="false">%1$s %2$s %3$s</string> + <string name="connection_assist_find_bridge_location_description">To find a bridge that can unblock your internet, we need to know where you’re connecting from.</string> + <string name="connection_assist_select_country_try_again">Select your country or region and try again.</string> + <!-- Connection assist. %1$s is connection_assist_find_bridge_location_description, %2$s is connection_assist_check_location_settings_try_again. %3$s is connection_assist_location_error_learn_more_link--> + <string name="connection_assist_location_error_last_try_description">%1$s %2$s %3$s</string> + <string name="connection_assist_check_location_settings_try_again">Please check your location settings are correct and try again.</string> + + <string name="connection_assist_location_error_learn_more_link">Learn more</string> + + <!-- Connection assist. --> + <string name="connection_assist_location_check_title">We’re still having trouble connecting</string> + + <!-- Connection assist. --> + <string name="connection_assist_last_try_title">Trying one more time…</string> + + <!-- Connection assist. --> + <string name="connection_assist_final_error_title">We weren’t able to connect automatically</string> + <!-- Connection assist. %1$s is connection_assist_final_error_troubleshoot_connection_link. %2$s is connection_assist_final_error_learn_more_link--> + <string name="connection_assist_final_error_description1">Despite our best efforts, we weren’t able to connect to Tor. We recommend %1$s and adding a bridge manually instead. %2$s</string> + <!-- Connection assist. --> + <string name="connection_assist_final_error_troubleshoot_connection_link">troubleshooting your connection</string> + <!-- Connection assist. --> + <string name="connection_assist_final_error_learn_more_link">Learn more</string> </resources>
===================================== fenix/tools/tba-fetch-deps.sh ===================================== @@ -14,7 +14,7 @@ fi
onion_proxy_library="$(ls -1td "$TOR_BROWSER_BUILD/out/tor-onion-proxy-library/"tor-onion-proxy-library-* | head -1)" if [ -z "$onion_proxy_library" ]; then - echo "Cannot find Tor Onoin Proxy library artifacts!" + echo "Cannot find Tor Onion Proxy library artifacts!" exit 2 fi
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/16f...