lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Download
Threads by month
  • ----- 2025 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
tbb-commits@lists.torproject.org

March 2024

  • 1 participants
  • 178 discussions
[Git][tpo/applications/tor-browser][base-browser-115.9.0esr-13.5-1] fixup! Bug 40925: Implemented the Security Level component
by Pier Angelo Vendrame (@pierov) 27 Mar '24

27 Mar '24
Pier Angelo Vendrame pushed to branch base-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: b0ff311a by Pier Angelo Vendrame at 2024-03-27T14:34:08+01:00 fixup! Bug 40925: Implemented the Security Level component Bug 42481: Modularize SecurityLevel. - - - - - 5 changed files: - browser/components/securitylevel/content/securityLevel.js - toolkit/components/search/SearchEngine.sys.mjs - toolkit/components/securitylevel/SecurityLevel.jsm → toolkit/components/securitylevel/SecurityLevel.sys.mjs - toolkit/components/securitylevel/components.conf - toolkit/components/securitylevel/moz.build Changes: ===================================== browser/components/securitylevel/content/securityLevel.js ===================================== @@ -2,11 +2,9 @@ /* global AppConstants, Services, openPreferences, XPCOMUtils */ -ChromeUtils.defineModuleGetter( - this, - "SecurityLevelPrefs", - "resource://gre/modules/SecurityLevel.jsm" -); +ChromeUtils.defineESModuleGetters(this, { + SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", +}); /* Security Level Button Code ===================================== toolkit/components/search/SearchEngine.sys.mjs ===================================== @@ -12,14 +12,9 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs", SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs", + SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", }); -ChromeUtils.defineModuleGetter( - lazy, - "SecurityLevelPrefs", - "resource://gre/modules/SecurityLevel.jsm" -); - const BinaryInputStream = Components.Constructor( "@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", ===================================== toolkit/components/securitylevel/SecurityLevel.jsm → toolkit/components/securitylevel/SecurityLevel.sys.mjs ===================================== @@ -1,17 +1,10 @@ -"use strict"; - -var EXPORTED_SYMBOLS = ["SecurityLevel", "SecurityLevelPrefs"]; - -const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); -const { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm"); +import { ConsoleAPI } from "resource://gre/modules/Console.sys.mjs"; const lazy = {}; -ChromeUtils.defineModuleGetter( - lazy, - "ExtensionParent", - "resource://gre/modules/ExtensionParent.jsm" -); +ChromeUtils.defineESModuleGetters(lazy, { + ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs", +}); const logger = new ConsoleAPI({ maxLogLevel: "info", @@ -263,6 +256,7 @@ var initializeNoScriptControl = () => { // bind NoScript settings to the browser.security_level.security_slider // (see noscript-control.js). /* eslint-disable */ +// prettier-ignore const kSecuritySettings = { // Preference name : [0, 1-high 2-m 3-m 4-low] "javascript.options.ion" : [, false, false, false, true ], @@ -427,7 +421,7 @@ function migratePreferences() { } // This class is used to initialize the security level stuff at the startup -class SecurityLevel { +export class SecurityLevel { QueryInterface = ChromeUtils.generateQI(["nsIObserver"]); init() { @@ -448,7 +442,7 @@ class SecurityLevel { Getters and Setters for relevant torbutton prefs */ -const SecurityLevelPrefs = { +export const SecurityLevelPrefs = { SecurityLevels: Object.freeze({ safest: 1, safer: 2, ===================================== toolkit/components/securitylevel/components.conf ===================================== @@ -4,7 +4,7 @@ Classes = [ "contract_ids": [ "@torproject.org/security-level;1", ], - "jsm": "resource://gre/modules/SecurityLevel.jsm", + "esModule": "resource://gre/modules/SecurityLevel.sys.mjs", "constructor": "SecurityLevel", } ] ===================================== toolkit/components/securitylevel/moz.build ===================================== @@ -1,5 +1,5 @@ EXTRA_JS_MODULES += [ - "SecurityLevel.jsm", + "SecurityLevel.sys.mjs", ] XPCOM_MANIFESTS += [ View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b0ff311… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/b0ff311… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.9.0esr-13.5-1] 2 commits: fixup! Add TorStrings module for localization
by Pier Angelo Vendrame (@pierov) 27 Mar '24

27 Mar '24
Pier Angelo Vendrame pushed to branch tor-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: 41d01e49 by Pier Angelo Vendrame at 2024-03-27T10:04:05+01:00 fixup! Add TorStrings module for localization Bug 42481: Modularize SecurityLevel. - - - - - 494af376 by Pier Angelo Vendrame at 2024-03-27T10:07:34+01:00 fixup! Bug 40925: Implemented the Security Level component Bug 42481: Modularize SecurityLevel. - - - - - 6 changed files: - browser/components/securitylevel/content/securityLevel.js - toolkit/components/search/SearchEngine.sys.mjs - toolkit/components/securitylevel/SecurityLevel.jsm → toolkit/components/securitylevel/SecurityLevel.sys.mjs - toolkit/components/securitylevel/components.conf - toolkit/components/securitylevel/moz.build - toolkit/modules/TorStrings.sys.mjs Changes: ===================================== browser/components/securitylevel/content/securityLevel.js ===================================== @@ -2,11 +2,9 @@ /* global AppConstants, Services, openPreferences, XPCOMUtils */ -ChromeUtils.defineModuleGetter( - this, - "SecurityLevelPrefs", - "resource://gre/modules/SecurityLevel.jsm" -); +ChromeUtils.defineESModuleGetters(this, { + SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", +}); /* Security Level Button Code ===================================== toolkit/components/search/SearchEngine.sys.mjs ===================================== @@ -12,14 +12,9 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs", SearchUtils: "resource://gre/modules/SearchUtils.sys.mjs", + SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", }); -ChromeUtils.defineModuleGetter( - lazy, - "SecurityLevelPrefs", - "resource://gre/modules/SecurityLevel.jsm" -); - const BinaryInputStream = Components.Constructor( "@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", ===================================== toolkit/components/securitylevel/SecurityLevel.jsm → toolkit/components/securitylevel/SecurityLevel.sys.mjs ===================================== @@ -1,17 +1,10 @@ -"use strict"; - -var EXPORTED_SYMBOLS = ["SecurityLevel", "SecurityLevelPrefs"]; - -const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); -const { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm"); +import { ConsoleAPI } from "resource://gre/modules/Console.sys.mjs"; const lazy = {}; -ChromeUtils.defineModuleGetter( - lazy, - "ExtensionParent", - "resource://gre/modules/ExtensionParent.jsm" -); +ChromeUtils.defineESModuleGetters(lazy, { + ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs", +}); const logger = new ConsoleAPI({ maxLogLevel: "info", @@ -263,6 +256,7 @@ var initializeNoScriptControl = () => { // bind NoScript settings to the browser.security_level.security_slider // (see noscript-control.js). /* eslint-disable */ +// prettier-ignore const kSecuritySettings = { // Preference name : [0, 1-high 2-m 3-m 4-low] "javascript.options.ion" : [, false, false, false, true ], @@ -427,7 +421,7 @@ function migratePreferences() { } // This class is used to initialize the security level stuff at the startup -class SecurityLevel { +export class SecurityLevel { QueryInterface = ChromeUtils.generateQI(["nsIObserver"]); init() { @@ -448,7 +442,7 @@ class SecurityLevel { Getters and Setters for relevant torbutton prefs */ -const SecurityLevelPrefs = { +export const SecurityLevelPrefs = { SecurityLevels: Object.freeze({ safest: 1, safer: 2, ===================================== toolkit/components/securitylevel/components.conf ===================================== @@ -4,7 +4,7 @@ Classes = [ "contract_ids": [ "@torproject.org/security-level;1", ], - "jsm": "resource://gre/modules/SecurityLevel.jsm", + "esModule": "resource://gre/modules/SecurityLevel.sys.mjs", "constructor": "SecurityLevel", } ] ===================================== toolkit/components/securitylevel/moz.build ===================================== @@ -1,5 +1,5 @@ EXTRA_JS_MODULES += [ - "SecurityLevel.jsm", + "SecurityLevel.sys.mjs", ] XPCOM_MANIFESTS += [ ===================================== toolkit/modules/TorStrings.sys.mjs ===================================== @@ -3,10 +3,7 @@ // 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/. -const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); -const { AppConstants } = ChromeUtils.import( - "resource://gre/modules/AppConstants.jsm" -); +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; function getLocale() { const locale = Services.locale.appLocaleAsBCP47; View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/9e01b1… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/9e01b1… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.5-1] 3 commits: fixup! Implement Android-native Connection Assist UI
by Dan Ballard (@dan) 26 Mar '24

26 Mar '24
Dan Ballard pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android Commits: 333d9284 by clairehurst at 2024-03-26T17:06:53-06:00 fixup! Implement Android-native Connection Assist UI - - - - - 86815386 by clairehurst at 2024-03-26T17:06:54-06:00 fixup! Bug 41878: Add standalone Tor Bootstrap - - - - - 99f95c30 by clairehurst at 2024-03-26T17:06:54-06:00 fixup! Add Tor integration and UI - - - - - 12 changed files: - fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.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/res/drawable/connect_broken.xml - + fenix/app/src/main/res/drawable/globe_broken.xml - fenix/app/src/main/res/drawable/tor_bootstrap_background_gradient.xml - fenix/app/src/main/res/layout/fragment_tor_connection_assist.xml - fenix/app/src/main/res/values/colors.xml - fenix/app/src/main/res/values/styles.xml Changes: ===================================== fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt ===================================== @@ -168,6 +168,7 @@ import java.util.Locale import androidx.navigation.fragment.findNavController import mozilla.components.browser.engine.gecko.GeckoEngine import mozilla.components.browser.state.selector.findCustomTab +import org.mozilla.fenix.home.HomeFragment import org.mozilla.geckoview.TorIntegrationAndroid /** @@ -815,6 +816,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIn final override fun onBackPressed() { supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach { + if (it is HomeFragment){ + finish() + return + } if (it is UserInteractionHandler && it.onBackPressed()) { return } ===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt ===================================== @@ -4,11 +4,19 @@ package org.mozilla.fenix.tor +import android.graphics.Color import android.os.Build import android.os.Bundle +import android.text.SpannableString +import android.text.Spanned +import android.text.TextPaint +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle @@ -22,6 +30,7 @@ import org.mozilla.fenix.ext.hideToolbar class TorConnectionAssistFragment : Fragment() { + private val TAG = "TorConnectionAssistFrag" private var _binding: FragmentTorConnectionAssistBinding? = null private val binding get() = _binding!! @@ -49,13 +58,14 @@ class TorConnectionAssistFragment : Fragment() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.torConnectState.collect { - when (it) { - TorConnectState.Initial -> showConfiguring() + viewModel.torConnectState.collect { torConnectState -> + Log.d(TAG, "torConnectState is ${torConnectState.state}") + when (torConnectState) { + TorConnectState.Initial -> showSplash() TorConnectState.Configuring -> showConfiguring() TorConnectState.AutoBootstrapping -> showBootstrapping() TorConnectState.Bootstrapping -> showBootstrapping() - TorConnectState.Error -> TODO() + TorConnectState.Error -> showError() TorConnectState.Bootstrapped -> openHome() TorConnectState.Disabled -> openHome() } @@ -73,59 +83,302 @@ class TorConnectionAssistFragment : Fragment() { } } - viewModel.quickconnectToggle().observe( - viewLifecycleOwner + viewModel.quickstartToggle().observe( + viewLifecycleOwner, ) { - binding.quickstartSwitch.isChecked = it + binding.quickstartSwitch.isChecked = it == true + } + + binding.quickstartSwitch.setOnCheckedChangeListener { _, isChecked -> + viewModel.handleQuickstartChecked(isChecked) } + } + + private fun showSplash() { + binding.torBootstrapProgressBar.visibility = View.GONE + binding.settingsButton.visibility = View.GONE + binding.backButton.visibility = View.GONE + binding.torConnectImage.visibility = View.GONE + binding.titleLargeTextView.visibility = View.GONE + binding.titleDescription.visibility = View.GONE + binding.quickStartDescription.visibility = View.GONE + binding.quickstartSwitch.visibility = View.GONE + binding.torBootstrapButton1.visibility = View.GONE + binding.torBootstrapButton2.visibility = View.GONE + binding.wordmarkLogo.visibility = View.VISIBLE + } + + + private fun showConfiguring() { + binding.wordmarkLogo.visibility = View.GONE + + binding.torBootstrapProgressBar.visibility = View.INVISIBLE + binding.torBootstrapProgressBar.progress = 0 + binding.backButton.visibility = View.INVISIBLE + binding.settingsButton.visibility = View.VISIBLE binding.settingsButton.setOnClickListener { viewModel.cancelTorBootstrap() openSettings() } + binding.torConnectImage.visibility = View.VISIBLE + binding.torConnectImage.setImageResource(R.drawable.connect) + binding.titleLargeTextView.visibility = View.VISIBLE + binding.titleLargeTextView.text = getString(R.string.connection_assist_tor_connect_title) + binding.titleDescription.visibility = View.VISIBLE + binding.titleDescription.text = + getString(R.string.preferences_tor_network_settings_explanation) + binding.quickStartDescription.visibility = View.VISIBLE + binding.quickstartSwitch.visibility = View.VISIBLE + binding.quickstartSwitch.isChecked = viewModel.quickstartToggle().value == true + + binding.unblockTheInternetInCountryDescription.visibility = View.GONE + binding.countryDropDown.visibility = View.GONE - binding.torBootstrapConnectButton.setOnClickListener { + binding.torBootstrapButton1.visibility = View.VISIBLE + binding.torBootstrapButton1.text = getString(R.string.tor_bootstrap_connect) + binding.torBootstrapButton1.setOnClickListener { viewModel.handleConnect(lifecycleScope = lifecycleScope) + showBootstrapping() } - binding.quickstartSwitch.setOnCheckedChangeListener { _, isChecked -> - viewModel.handleQuickstartChecked(isChecked) + binding.torBootstrapButton2.visibility = View.VISIBLE + binding.torBootstrapButton2.text = + getString(R.string.connection_assist_configure_connection_button) + binding.torBootstrapButton2.setOnClickListener { + viewModel.cancelTorBootstrap() + openTorNetworkSettings() } } - private fun showConfiguring() { - binding.torBootstrapConnectButton.visibility = View.VISIBLE - binding.torBootstrapNetworkSettingsButton.text = + private fun showBootstrapping() { + binding.wordmarkLogo.visibility = View.GONE + + binding.torBootstrapProgressBar.visibility = View.VISIBLE + binding.torBootstrapProgressBar.progress = 0 + binding.backButton.visibility = View.INVISIBLE + binding.settingsButton.visibility = View.VISIBLE + binding.settingsButton.setOnClickListener { + viewModel.cancelTorBootstrap() + openSettings() + } + binding.torConnectImage.visibility = View.VISIBLE + binding.torConnectImage.setImageResource(R.drawable.connect) + binding.titleLargeTextView.visibility = View.VISIBLE + binding.titleLargeTextView.text = getString(R.string.connection_assist_connecting_title) + binding.titleDescription.visibility = View.VISIBLE + binding.titleDescription.text = + getString(R.string.preferences_tor_network_settings_explanation) + binding.quickstartSwitch.visibility = View.VISIBLE + binding.quickstartSwitch.isChecked = viewModel.quickstartToggle().value == true + binding.quickstartSwitch.jumpDrawablesToCurrentState() + binding.quickStartDescription.visibility = View.VISIBLE + binding.torBootstrapButton1.visibility = View.INVISIBLE + binding.torBootstrapButton2.visibility = View.VISIBLE + binding.torBootstrapButton2.text = getString(R.string.btn_cancel) + binding.torBootstrapButton2.setOnClickListener { viewModel.cancelTorBootstrap() } + } + + private suspend fun showError() { + viewModel.torError.collect { + Log.d( + TAG, + "TorError: details = ${it?.details ?: "null details"}, message = ${it?.message ?: "null message"}", + ) + when (viewModel.handleError(it)) { + ErrorScreen.CantConnectToInternet -> showCantConnectToInternet() + ErrorScreen.CantConnectToTorDirectly -> showCantConnectToTorDirectly() + ErrorScreen.WeCouldntFindYourLocation -> showWeCouldntFindYourLocation() + ErrorScreen.WereStillHavingTroubleConnecting -> showWereStillHavingTroubleConnecting() + ErrorScreen.WeWerentAbleToConnectAutomatically -> showWeWerentAbleToConnectAutomatically() + null -> { + // no op + Log.d(TAG, "ErrorScreen: null, nothing shown") + } + } + } + } + + private fun showCantConnectToInternet() { + Log.d(TAG, "showCantConnectToInternet()") + binding.torBootstrapProgressBar.visibility = View.VISIBLE + binding.torBootstrapProgressBar.progressTintList = + AppCompatResources.getColorStateList(requireContext(), R.color.warning_yellow) + binding.torBootstrapProgressBar.progress = 100 + + binding.backButton.visibility = View.VISIBLE + binding.backButton.setOnClickListener { + showConfiguring() + } + + binding.torConnectImage.setImageResource(R.drawable.globe_broken) + binding.titleLargeTextView.text = getString(R.string.connection_assist_internet_error_title) + + val learnMore: String = getString(R.string.connection_assist_internet_error_learn_more) + val internetErrorDescription: String = getString( + R.string.connection_assist_internet_error_description, + learnMore, + ) + handleDescriptionWithClickable(internetErrorDescription, learnMore) + + binding.quickStartDescription.visibility = View.GONE + binding.quickstartSwitch.visibility = View.GONE + + binding.torBootstrapButton1.visibility = View.VISIBLE + binding.torBootstrapButton1.text = + getString(R.string.connection_assist_internet_error_try_again) + binding.torBootstrapButton1.setOnClickListener { + showTryingAgain() + viewModel.handleConnect(lifecycleScope = lifecycleScope) + } + + binding.torBootstrapButton2.text = getString(R.string.connection_assist_configure_connection_button) - binding.torBootstrapNetworkSettingsButton.setOnClickListener { + binding.torBootstrapButton2.setOnClickListener { openTorNetworkSettings() } } - private fun showBootstrapping() { - binding.torBootstrapConnectButton.visibility = View.INVISIBLE - binding.torBootstrapNetworkSettingsButton.text = getString(R.string.btn_cancel) - binding.torBootstrapNetworkSettingsButton.setOnClickListener { + private fun showTryingAgain() { + Log.d(TAG, "showTryingAgain()") + binding.torBootstrapProgressBar.progress = 0 + binding.torBootstrapProgressBar.visibility = View.VISIBLE + binding.torBootstrapProgressBar.progressTintList = null + binding.torConnectImage.setImageResource(R.drawable.connect) + binding.titleLargeTextView.text = + getString(R.string.connection_assist_trying_again_waiting_title) + + binding.quickstartSwitch.visibility = View.GONE + binding.quickStartDescription.visibility = View.GONE + binding.torBootstrapButton1.visibility = View.INVISIBLE + binding.torBootstrapButton2.visibility = View.VISIBLE + binding.torBootstrapButton2.text = getString(R.string.btn_cancel) + binding.torBootstrapButton2.setOnClickListener { viewModel.cancelTorBootstrap() + showConfiguring() } } - private fun openSettings(preferenceToScrollTo: String? = null) { - findNavController().navigate( - TorConnectionAssistFragmentDirections - .actionTorConnectionAssistFragmentToSettingsFragment(preferenceToScrollTo), + private fun showCantConnectToTorDirectly() { + Log.d(TAG, "showCantConnectToTorDirectly()") + binding.torBootstrapProgressBar.visibility = View.VISIBLE + binding.torBootstrapProgressBar.progressTintList = + AppCompatResources.getColorStateList(requireContext(), R.color.warning_yellow) + binding.torBootstrapProgressBar.progress = 100 + + binding.backButton.visibility = View.VISIBLE + binding.backButton.setOnClickListener { + showConfiguring() + } + + binding.torConnectImage.setImageResource(R.drawable.globe_broken) + binding.titleLargeTextView.text = + getString(R.string.connection_assist_cant_connect_to_tor_title) + + val learnMore: String = getString(R.string.connection_assist_internet_error_learn_more) + val tryABridge: String = getString( + R.string.connection_assist_try_a_bridge_description, + learnMore, ) + handleDescriptionWithClickable(tryABridge, learnMore) + + binding.quickStartDescription.visibility = View.GONE + binding.quickstartSwitch.visibility = View.GONE + binding.unblockTheInternetInCountryDescription.visibility = View.VISIBLE + binding.countryDropDown.visibility = View.VISIBLE + // TODO implement countryDropDown + + binding.torBootstrapButton1.visibility = View.VISIBLE + binding.torBootstrapButton1.text = getString(R.string.connection_assist_try_a_bridge_button) + binding.torBootstrapButton1.setOnClickListener { + viewModel.tryABridge() + showTryingABridge() + } + binding.torBootstrapButton2.visibility = View.GONE } - private fun openTorNetworkSettings() { - findNavController().navigate( - TorConnectionAssistFragmentDirections - .actionTorConnectionAssistFragmentToTorNetworkSettings(), + private fun showTryingABridge() { + Log.d(TAG, "showTryingABridge()") + // TODO(Not implemented) + binding.torBootstrapButton2.setOnClickListener { + showTryingABridge() + } + } + + private fun showWeCouldntFindYourLocation() { + Log.d(TAG, "showWeCouldntFindYourLocation()") + // TODO(Not implemented) + binding.torBootstrapButton2.setOnClickListener { + showTryingABridge() + } + } + + private fun showWereStillHavingTroubleConnecting() { + Log.d(TAG, "showWereStillHavingTroubleConnecting()") + TODO("Not yet implemented") + } + + private fun showTryingOneMoreTime() { + Log.d(TAG, "showTryingOneMoreTime()") + TODO("Not yet implemented") + } + + private fun showWeWerentAbleToConnectAutomatically() { + Log.d(TAG, "showWeWerentAbleToConnectAutomatically()") + TODO("Not yet implemented") + } + + private fun showUnknownError() { + Log.d(TAG, "showUnknownError()") + TODO("Not yet implemented") + } + + /** + * from https://stackoverflow.com/questions/10696986/how-to-set-the-part-of-the-tex… + */ + private fun handleDescriptionWithClickable(errorDescription: String, learnMore: String) { + val errorDescriptionSpannableString = SpannableString(errorDescription) + val clickableSpan: ClickableSpan = object : ClickableSpan() { + override fun onClick(textView: View) { + showLearnMore() + } + + override fun updateDrawState(drawState: TextPaint) { + super.updateDrawState(drawState) + drawState.isUnderlineText = true + } + } + errorDescriptionSpannableString.setSpan( + clickableSpan, + errorDescription.length - learnMore.length, + errorDescription.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE, ) + binding.titleDescription.text = errorDescriptionSpannableString + binding.titleDescription.movementMethod = LinkMovementMethod.getInstance() + binding.titleDescription.highlightColor = Color.TRANSPARENT + } + + private fun showLearnMore() { + //TODO("Not yet implemented") } private fun openHome() { + Log.d(TAG, "openHome()") //This doesn't seem to be ever called findNavController().navigate(TorConnectionAssistFragmentDirections.actionStartupHome()) } + private fun openSettings(preferenceToScrollTo: String? = null) { + findNavController().navigate( + TorConnectionAssistFragmentDirections.actionTorConnectionAssistFragmentToSettingsFragment( + preferenceToScrollTo, + ), + ) + } + + private fun openTorNetworkSettings() { + findNavController().navigate( + TorConnectionAssistFragmentDirections.actionTorConnectionAssistFragmentToTorNetworkSettings(), + ) + } } ===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistViewModel.kt ===================================== @@ -26,24 +26,30 @@ class TorConnectionAssistViewModel( private val _torConnectState = MutableStateFlow(TorConnectState.Initial) internal val torConnectState: StateFlow<TorConnectState> = _torConnectState - init { - _torController.registerTorListener(this) - } + private val _torError = MutableStateFlow(_torController.getLastErrorState()) + internal val torError: StateFlow<TorError?> = _torError private val _progress = MutableLiveData(0) fun progress(): LiveData<Int> { return _progress } - private val _quickconnectToggle = MutableLiveData(_torController.quickstart) - fun quickconnectToggle(): LiveData<Boolean> { - return _quickconnectToggle + private val _quickStartToggle = MutableLiveData<Boolean>() // don't initialize with quickstart off the bat + fun quickstartToggle(): LiveData<Boolean?> { + _quickStartToggle.value = _torController.quickstart // quickstart isn't ready until torSettings is ready + return _quickStartToggle + } + + init { + Log.d(TAG, "initiating TorConnectionAssistViewModel") + _torController.registerTorListener(this) } fun handleConnect( withDebugLogging: Boolean = false, lifecycleScope: LifecycleCoroutineScope? = null, ) { + Log.d(TAG, "handleConnect initiatingTorBootstrap with lifecycleScope = $lifecycleScope") _torController.initiateTorBootstrap( withDebugLogging = withDebugLogging, lifecycleScope = lifecycleScope, @@ -52,6 +58,7 @@ class TorConnectionAssistViewModel( fun handleQuickstartChecked(checked: Boolean) { _torController.quickstart = checked + _quickStartToggle.value = checked } fun cancelTorBootstrap() { @@ -66,7 +73,6 @@ class TorConnectionAssistViewModel( override fun onTorConnected() { Log.d(TAG, "onTorConnected()") _torController.unregisterTorListener(this) - _torConnectState.value = _torController.lastKnownStatus } override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) { @@ -75,12 +81,32 @@ class TorConnectionAssistViewModel( _progress.value = progress.toInt() } _torConnectState.value = _torController.lastKnownStatus + _torError.value = _torController.getLastErrorState() } override fun onTorStopped() { Log.d(TAG, "onTorStopped()") - _progress.value = 0 - _torConnectState.value = _torController.lastKnownStatus } + internal fun handleError(it: TorError?): ErrorScreen? { + // TODO(Only partly implemented) + if (it?.message == null){ + return null + } + return ErrorScreen.CantConnectToInternet + } + + fun tryABridge() { + // TODO("Try a bridge not enabled") + // connect to bridge based on country + // try connecting + } +} + +internal enum class ErrorScreen { + CantConnectToInternet, + CantConnectToTorDirectly, + WeCouldntFindYourLocation, + WereStillHavingTroubleConnecting, + WeWerentAbleToConnectAutomatically, } ===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorController.kt ===================================== @@ -12,6 +12,10 @@ interface TorEvents { fun onTorStatusUpdate(entry: String?, status: String?, progress: Double? = 0.0) fun onTorStopped() } +class TorError( + var message: String, + var details: String +) { } internal enum class TorStatus(val status: String) { OFF("OFF"), @@ -59,6 +63,8 @@ interface TorController: TorEvents { override fun onTorStatusUpdate(entry: String?, status: String?, progress: Double?) override fun onTorStopped() + fun getLastErrorState() : TorError? + fun registerTorListener(l: TorEvents) fun unregisterTorListener(l: TorEvents) ===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerGV.kt ===================================== @@ -53,6 +53,7 @@ class TorControllerGV( private var torListeners = mutableListOf<TorEvents>() internal var lastKnownStatus = TorConnectState.Initial + internal var lastKnownError: TorError? = null private var wasTorBootstrapped = false private var isTorRestarting = false @@ -210,6 +211,7 @@ class TorControllerGV( override fun setTorStopped() { lastKnownStatus = TorConnectState.Configuring + onTorStatusUpdate(null, lastKnownStatus.toString(), 0.0) onTorStopped() } @@ -227,6 +229,10 @@ class TorControllerGV( } } + override fun getLastErrorState() : TorError? { + return lastKnownError + } + // TorEventsBootstrapStateChangeListener -> (lastKnowStatus, TorEvents) // Handle events from GeckoView TorAndroidIntegration and map to TorEvents based events // and state for firefox-android (designed for tor-android-service) @@ -263,7 +269,7 @@ class TorControllerGV( } lastKnownStatus = newState - + onTorStatusUpdate(null, newStateVal, null) } // TorEventsBootstrapStateChangeListener @@ -290,7 +296,7 @@ class TorControllerGV( // TorEventsBootstrapStateChangeListener override fun onBootstrapError(message: String?, details: String?) { - lastKnownStatus = TorConnectState.Error + lastKnownError = TorError(message ?: "", details ?: "") onBootstrapStateChange(TorConnectState.Error.state) } ===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerTAS.kt ===================================== @@ -330,4 +330,10 @@ class TorControllerTAS (private val context: Context): TorController { companion object { const val torServiceResponseTimeout = 5000L } + + // Compat with TorControlGV Stubs + + override fun getLastErrorState() : TorError? { + return null; + } } ===================================== fenix/app/src/main/res/drawable/connect_broken.xml ===================================== @@ -0,0 +1,37 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="40dp" + android:height="40dp" + android:viewportWidth="40" + android:viewportHeight="40"> + <group> + <clip-path + android:pathData="M0,0h40v40h-40z"/> + <path + android:pathData="M8.317,5.337C11.521,2.781 15.582,1.253 19.999,1.253C30.352,1.253 38.745,9.647 38.745,20C38.745,24.418 37.218,28.478 34.662,31.681L32.577,29.597C34.611,26.937 35.819,23.611 35.819,20C35.819,11.26 28.739,4.18 19.999,4.18C16.389,4.18 13.063,5.388 10.401,7.421L8.317,5.337Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M5.89,7.656C3.002,10.954 1.252,15.273 1.252,20C1.252,28.967 7.545,36.46 15.959,38.307C16.839,38.5 17.732,38.633 18.652,38.693V24.373C16.785,23.8 15.425,22.06 15.425,20C15.425,19.19 15.635,18.43 16.004,17.771L13.887,15.653C13.013,16.88 12.499,18.38 12.499,20C12.499,22.653 13.879,24.987 15.959,26.32V35.293C9.179,33.513 4.179,27.347 4.179,20C4.179,16.08 5.603,12.493 7.963,9.73L5.89,7.656Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M16.399,13.419L18.618,15.638C19.054,15.501 19.517,15.427 19.998,15.427C22.525,15.427 24.572,17.473 24.572,20C24.572,20.481 24.498,20.945 24.36,21.38L26.579,23.599C27.165,22.531 27.498,21.304 27.498,20C27.498,15.86 24.138,12.5 19.998,12.5C18.694,12.5 17.468,12.833 16.399,13.419Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M24.349,26.112L22.232,23.995C21.954,24.151 21.658,24.278 21.349,24.373V38.693C22.269,38.633 23.162,38.5 24.042,38.307C27.176,37.619 30.015,36.147 32.345,34.109L30.271,32.034C28.492,33.552 26.372,34.681 24.042,35.293V26.32C24.146,26.253 24.249,26.184 24.349,26.112Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M30.653,27.67C32.21,25.514 33.127,22.864 33.127,20C33.127,12.753 27.247,6.873 20,6.873C17.138,6.873 14.488,7.791 12.33,9.348L14.437,11.455C16.037,10.412 17.947,9.807 20,9.807C25.634,9.807 30.194,14.367 30.194,20C30.194,22.051 29.587,23.962 28.544,25.562L30.653,27.67Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M26.272,28.037L28.357,30.121C27.095,31.163 25.635,31.973 24.041,32.487V29.36C24.844,29.014 25.593,28.568 26.272,28.037Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M11.962,13.727L9.878,11.643C8.001,13.914 6.873,16.826 6.873,20C6.873,25.84 10.686,30.787 15.96,32.487V29.36C12.34,27.8 9.806,24.193 9.806,20C9.806,17.633 10.611,15.457 11.962,13.727Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M17.922,19.688L20.311,22.077C20.21,22.092 20.105,22.1 19.999,22.1C18.84,22.1 17.899,21.16 17.899,20C17.899,19.894 17.907,19.79 17.922,19.688Z" + android:fillColor="#FBFBFE"/> + <path + android:pathData="M2.89,4.642L35.228,36.98C35.879,37.632 35.879,38.688 35.228,39.339L35.228,39.339C34.576,39.991 33.52,39.991 32.868,39.339L0.53,7.001C-0.121,6.35 -0.121,5.294 0.53,4.642C1.182,3.991 2.238,3.991 2.89,4.642Z" + android:fillColor="#FBFBFE"/> + </group> +</vector> ===================================== fenix/app/src/main/res/drawable/globe_broken.xml ===================================== @@ -0,0 +1,18 @@ +<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="M4.209,1.999L37.355,35.145L35.145,37.355L1.999,4.209L4.209,1.999Z" + android:fillColor="#FBFBFE" + android:fillType="evenOdd"/> + <path + android:pathData="M7.869,5.703C3.82,9.142 1.25,14.271 1.25,20C1.25,30.03 9.126,38.221 19.031,38.725L19.041,38.733L19.047,38.726C19.363,38.742 19.681,38.75 20,38.75C20.32,38.75 20.638,38.742 20.954,38.726L20.96,38.733L20.97,38.725C26.306,38.453 31.053,35.951 34.297,32.132L32.079,29.913C30.228,32.166 27.759,33.891 24.931,34.831C26.854,32.438 28.243,29.75 29.097,26.931L26.534,24.368C25.642,28.517 23.465,32.438 20,35.474C15.763,31.76 13.451,26.722 13.063,21.563H23.728L20.603,18.438H13.063C13.22,16.35 13.692,14.282 14.479,12.313L12.102,9.936C10.844,12.632 10.12,15.52 9.93,18.438H4.453C4.872,14.209 6.978,10.477 10.087,7.922L7.869,5.703ZM15.069,34.831C11.952,30.951 10.239,26.295 9.93,21.563H4.453C5.07,27.779 9.331,32.924 15.069,34.831Z" + android:fillColor="#FBFBFE" + android:fillType="evenOdd"/> + <path + android:pathData="M13.678,7.093C14.106,6.433 14.569,5.791 15.069,5.169C14.263,5.437 13.486,5.769 12.744,6.159L10.448,3.863C12.985,2.358 15.907,1.434 19.031,1.275L19.041,1.267L19.047,1.274C19.363,1.258 19.681,1.25 20,1.25C20.32,1.25 20.638,1.258 20.954,1.274L20.96,1.267L20.97,1.275C30.875,1.779 38.75,9.97 38.75,20C38.75,23.489 37.798,26.755 36.138,29.553L33.842,27.257C34.752,25.525 35.346,23.601 35.548,21.563H30.071C30.033,22.146 29.974,22.728 29.893,23.308L25.023,18.438H26.938C26.55,13.278 24.238,8.24 20,4.526C18.361,5.963 17.01,7.598 15.947,9.361L13.678,7.093ZM30.071,18.438H35.548C34.931,12.221 30.67,7.076 24.931,5.169C28.049,9.049 29.762,13.705 30.071,18.438Z" + android:fillColor="#FBFBFE" + android:fillType="evenOdd"/> +</vector> ===================================== fenix/app/src/main/res/drawable/tor_bootstrap_background_gradient.xml ===================================== @@ -7,9 +7,9 @@ <shape> <gradient android:angle="225" - android:startColor="#FF7329A4" - android:centerColor="#FF3A3274" - android:endColor="#FF3A3274" + android:startColor="@color/backgroundGradientLight" + android:centerColor="@color/backgroundGradientDark" + android:endColor="@color/backgroundGradientDark" android:type="linear" /> </shape> </item> ===================================== fenix/app/src/main/res/layout/fragment_tor_connection_assist.xml ===================================== @@ -3,29 +3,63 @@ - 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" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@drawable/tor_bootstrap_background_gradient"> + android:background="@drawable/tor_bootstrap_background_gradient" + android:paddingBottom="16dp"> <ProgressBar android:id="@+id/tor_bootstrap_progress_bar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="6dp" + android:visibility="invisible" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - <ImageView + <androidx.constraintlayout.widget.ConstraintLayout 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" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:srcCompat="@drawable/mozac_ic_settings" /> + app:layout_constraintTop_toTopOf="parent"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@string/settings" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/mozac_ic_settings" /> + </androidx.constraintlayout.widget.ConstraintLayout> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/back_button" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:visibility="invisible" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@string/settings" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/mozac_ic_back" /> + </androidx.constraintlayout.widget.ConstraintLayout> + <ImageView android:id="@+id/tor_connect_image" @@ -45,99 +79,139 @@ 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_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/tor_connect_image" /> + app:layout_constraintTop_toBottomOf="@id/tor_connect_image" + app:layout_constraintVertical_bias="0.03" /> <TextView - android:id="@+id/connect_to_tor_description" + android:id="@+id/title_description" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="24dp" - android:layout_marginTop="16dp" android:layout_marginEnd="24dp" + android:lineSpacingExtra="6dp" android:text="@string/preferences_tor_network_settings_explanation" android:textColor="#FBFBFE" - android:textFontWeight="400" android:textSize="14sp" + app:layout_constraintBottom_toBottomOf="parent" 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" /> + app:layout_constraintTop_toBottomOf="@id/title_large_text_view" + app:layout_constraintVertical_bias="0.03" /> + <TextView - android:id="@+id/connect_automatically" - android:layout_width="wrap_content" + android:id="@+id/quick_start_description" + android:layout_width="230dp" 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="#80FBFBFE" + android:textColor="#FBFBFE" android:textSize="14sp" - app:layout_constraintBottom_toBottomOf="@+id/quickstart_switch" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/quickstart_switch" - app:layout_constraintVertical_bias="1.25" /> + app:layout_constraintTop_toBottomOf="@+id/title_description" + app:layout_constraintVertical_bias=".03" /> <androidx.appcompat.widget.SwitchCompat android:id="@+id/quickstart_switch" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="24dp" + android:layout_marginStart="100dp" android:layout_marginEnd="24dp" android:layout_marginBottom="24dp" - android:enabled="false" android:gravity="center" - app:thumbTint="#7D6298" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/connect_to_tor_description" + app:layout_constraintHorizontal_bias="0" + app:layout_constraintStart_toEndOf="@+id/quick_start_description" + app:layout_constraintTop_toBottomOf="@id/title_description" + app:layout_constraintVertical_bias=".023" app:layout_goneMarginEnd="6dp" app:layout_goneMarginTop="9dp" /> - <Button - android:id="@+id/tor_bootstrap_connect_button" + <TextView + android:id="@+id/unblock_the_internet_in_country_description" + 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_unblock_the_internet_in_country_or_region" + android:textColor="#FBFBFE" + android:visibility="invisible" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/title_description" /> + + <androidx.appcompat.widget.AppCompatSpinner + android:id="@+id/country_drop_down" + style="@style/Widget.AppCompat.Spinner.Underlined" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="24dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="24dp" + android:textColor="#FBFBFE" + android:tooltipText="@string/connection_assist_share_my_location_country_or_region" + android:visibility="invisible" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/unblock_the_internet_in_country_description" /> + + <ImageView + android:id="@+id/wordmarkLogo" + android:layout_width="160dp" + android:layout_height="160dp" + android:src="@mipmap/ic_launcher_round" + + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + android:contentDescription="" /> + + <Button + android:id="@+id/tor_bootstrap_button_1" + android:layout_width="wrap_content" + 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:minWidth="360dp" 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_constraintBottom_toTopOf="@id/tor_bootstrap_button_2" 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:id="@+id/tor_bootstrap_button_2" + android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" - android:layout_marginBottom="24dp" + android:layout_marginBottom="8dp" android:background="@drawable/rounded_corners" android:backgroundTint="@color/configure_connection_button_white" - android:maxWidth="312dp" + android:minWidth="360dp" 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" ===================================== fenix/app/src/main/res/values/colors.xml ===================================== @@ -273,6 +273,8 @@ <color name="sync_disconnected_background_private_theme">#5B5846</color> <color name="onboarding_illustration_deselected_private_theme">#99FBFBFE</color> <color name="prompt_login_edit_text_cursor_color_private_theme">@color/photonViolet50</color> + <color name="backgroundGradientDark">#FF3A3274</color> + <color name="backgroundGradientLight">#FF7329A4</color> <!-- Normal theme colors for light mode --> <color name="accent_normal_theme">@color/photonInk20</color> @@ -344,5 +346,6 @@ <!-- Connection Assist --> <color name="connect_button_purple">#9059FF</color> <color name="configure_connection_button_white">#E1E0E7</color> + <color name="warning_yellow">#FFA436</color> </resources> ===================================== fenix/app/src/main/res/values/styles.xml ===================================== @@ -12,7 +12,7 @@ <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item> <item name="android:progressBarStyleHorizontal">@style/progressBarStyleHorizontal</item> <item name="android:statusBarColor">@android:color/transparent</item> - <item name="android:windowBackground">@color/fx_mobile_layer_color_1</item> + <item name="android:windowBackground">@color/backgroundGradientDark</item> <item name="android:colorEdgeEffect">@color/accent_normal_theme</item> <item name="android:colorAccent">@color/fx_mobile_text_color_primary</item> <item name="android:textColorPrimary">@color/state_list_text_color</item> View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/5a… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/5a… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.5-1] fixup! Disable features and functionality
by Dan Ballard (@dan) 26 Mar '24

26 Mar '24
Dan Ballard pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android Commits: 5ab6ae0a by clairehurst at 2024-03-25T13:01:48-06:00 fixup! Disable features and functionality - - - - - 1 changed file: - android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt Changes: ===================================== android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/ui/AddonsManagerAdapter.kt ===================================== @@ -316,7 +316,7 @@ class AddonsManagerAdapter( } // Add recommended section and addons if available - if (recommendedAddons.isNotEmpty()) { + if (false) { // recommendedAddons.isNotEmpty() tor-browser#40502: Do not recommend addons on Tor Browser itemsWithSections.add(Section(R.string.mozac_feature_addons_recommended_section, true)) val filteredRecommendedAddons = recommendedAddons.filter { it.id !in excludedAddonIDs View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/5ab… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/5ab… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.9.0esr-13.5-1] fixup! Bug 42247: Android helpers for the TorProvider
by Pier Angelo Vendrame (@pierov) 26 Mar '24

26 Mar '24
Pier Angelo Vendrame pushed to branch tor-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: 9e01b1a9 by Dan Ballard at 2024-03-26T11:33:26-07:00 fixup! Bug 42247: Android helpers for the TorProvider Bug 41187: Add support for tor logs in android integration - - - - - 4 changed files: - mobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorIntegrationAndroid.java - toolkit/components/tor-launcher/TorProvider.sys.mjs - toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs - toolkit/modules/TorAndroidIntegration.sys.mjs Changes: ===================================== mobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorIntegrationAndroid.java ===================================== @@ -46,6 +46,7 @@ public class TorIntegrationAndroid implements BundleEventListener { private static final String EVENT_BOOTSTRAP_PROGRESS = "GeckoView:Tor:BootstrapProgress"; private static final String EVENT_BOOTSTRAP_COMPLETE = "GeckoView:Tor:BootstrapComplete"; private static final String EVENT_BOOTSTRAP_ERROR = "GeckoView:Tor:BootstrapError"; + private static final String EVENT_TOR_LOGS = "GeckoView:Tor:Logs"; private static final String EVENT_SETTINGS_READY = "GeckoView:Tor:SettingsReady"; private static final String EVENT_SETTINGS_CHANGED = "GeckoView:Tor:SettingsChanged"; private static final String EVENT_SETTINGS_OPEN = "GeckoView:Tor:OpenSettings"; @@ -118,6 +119,7 @@ public class TorIntegrationAndroid implements BundleEventListener { EVENT_BOOTSTRAP_PROGRESS, EVENT_BOOTSTRAP_COMPLETE, EVENT_BOOTSTRAP_ERROR, + EVENT_TOR_LOGS, EVENT_SETTINGS_OPEN); } @@ -168,6 +170,12 @@ public class TorIntegrationAndroid implements BundleEventListener { for (BootstrapStateChangeListener listener: mBootstrapStateListeners) { listener.onBootstrapError(msg, details); } + } else if (EVENT_TOR_LOGS.equals(event)) { + String msg = message.getString("message"); + String type = message.getString("logType"); + for (TorLogListener listener: mLogListeners) { + listener.onLog(type, msg); + } } else if (EVENT_SETTINGS_OPEN.equals(event)) { for (BootstrapStateChangeListener listener: mBootstrapStateListeners) { listener.onSettingsRequested(); @@ -573,6 +581,10 @@ public class TorIntegrationAndroid implements BundleEventListener { void onSettingsRequested(); } + public interface TorLogListener { + void onLog(String logType, String message); + } + private @NonNull void reloadSettings() { EventDispatcher.getInstance().queryBundle(EVENT_SETTINGS_GET).then( new GeckoResult.OnValueListener<GeckoBundle, Void>() { public GeckoResult<Void> onValue(final GeckoBundle bundle) { @@ -647,4 +659,14 @@ public class TorIntegrationAndroid implements BundleEventListener { } private final HashSet<BootstrapStateChangeListener> mBootstrapStateListeners = new HashSet<>(); + + public void registerLogListener(TorLogListener listener) { + mLogListeners.add(listener); + } + + public void unregisterLogListener(TorLogListener listener) { + mLogListeners.remove(listener); + } + + private final HashSet<TorLogListener> mLogListeners = new HashSet<>(); } ===================================== toolkit/components/tor-launcher/TorProvider.sys.mjs ===================================== @@ -1002,6 +1002,8 @@ export class TorProvider { Services.obs.notifyObservers(null, TorProviderTopics.HasWarnOrErr); } + Services.obs.notifyObservers({ type, msg }, TorProviderTopics.TorLog); + const date = new Date(); const maxEntries = Services.prefs.getIntPref( Preferences.MaxLogEntries, ===================================== toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs ===================================== @@ -12,6 +12,7 @@ export const TorProviderTopics = Object.freeze({ ProcessExited: "TorProcessExited", BootstrapStatus: "TorBootstrapStatus", BootstrapError: "TorBootstrapError", + TorLog: "TorLog", HasWarnOrErr: "TorLogHasWarnOrErr", BridgeChanged: "TorBridgeChanged", CircuitCredentialsMatched: "TorCircuitCredentialsMatched", ===================================== toolkit/modules/TorAndroidIntegration.sys.mjs ===================================== @@ -11,6 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, { TorConnectTopics: "resource://gre/modules/TorConnect.sys.mjs", TorSettingsTopics: "resource://gre/modules/TorSettings.sys.mjs", TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs", + TorProviderTopics: "resource://gre/modules/TorProviderBuilder.sys.mjs", TorSettings: "resource://gre/modules/TorSettings.sys.mjs", }); @@ -32,6 +33,7 @@ const EmittedEvents = Object.freeze({ bootstrapProgress: "GeckoView:Tor:BootstrapProgress", bootstrapComplete: "GeckoView:Tor:BootstrapComplete", bootstrapError: "GeckoView:Tor:BootstrapError", + torLogs: "GeckoView:Tor:Logs", }); const ListenedEvents = Object.freeze({ @@ -59,6 +61,8 @@ class TorAndroidIntegrationImpl { this.#bootstrapMethodReset(); Services.prefs.addObserver(Prefs.useNewBootstrap, this); + Services.obs.addObserver(this, lazy.TorProviderTopics.TorLog); + for (const topic in lazy.TorConnectTopics) { Services.obs.addObserver(this, lazy.TorConnectTopics[topic]); } @@ -118,6 +122,13 @@ class TorAndroidIntegrationImpl { details: subj.wrappedJSObject.details ?? "", }); break; + case lazy.TorProviderTopics.TorLog: + lazy.EventDispatcher.instance.sendRequest({ + type: EmittedEvents.torLogs, + logType: subj.wrappedJSObject.type ?? "", + message: subj.wrappedJSObject.msg ?? "", + }); + break; case lazy.TorSettingsTopics.Ready: lazy.EventDispatcher.instance.sendRequest({ type: EmittedEvents.settingsReady, View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/9e01b1a… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/9e01b1a… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-115.9.0esr-13.5-1] fixup! Bug 40925: Implemented the Security Level component
by richard (@richard) 26 Mar '24

26 Mar '24
richard pushed to branch mullvad-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Mullvad Browser Commits: ea97107e by Henry Wilkes at 2024-03-26T17:56:27+00:00 fixup! Bug 40925: Implemented the Security Level component Bug 42214: Drop the securityLevel.properties file. - - - - - 1 changed file: - − browser/locales/en-US/chrome/browser/securityLevel.properties Changes: ===================================== browser/locales/en-US/chrome/browser/securityLevel.properties deleted ===================================== @@ -1,33 +0,0 @@ -# Generic terms -security_level = Security Level -security_level_standard = Standard -security_level_safer = Safer -security_level_safest = Safest -security_level_tooltip_standard = Security Level: Standard -security_level_tooltip_safer = Security Level: Safer -security_level_tooltip_safest = Security Level: Safest -# Shown only for custom level -security_level_custom = Custom -security_level_restore = Restore Defaults -security_level_learn_more = Learn more - -# Panel button that takes the user to the security level settings in -# about:preferences#privacy -security_level_open_settings = Settings… -security_level_change = Change… -security_level_standard_summary = All browser and website features are enabled. -security_level_safer_summary = Disables website features that are often dangerous, causing some sites to lose functionality. -security_level_safest_summary = Only allows website features required for static sites and basic services. These changes affect images, media, and scripts. -security_level_custom_heading = Custom security level configured -security_level_custom_summary = Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels. - -## Security level section in about:preferences#privacy -security_level_overview = Disable certain web features that can be used to attack your security and anonymity. -security_level_list_safer = At the safer setting: -security_level_list_safest = At the safest setting: -# Strings for descriptions -security_level_js_https_only = JavaScript is disabled on non-HTTPS sites. -security_level_js_disabled = JavaScript is disabled by default on all sites. -security_level_limit_typography = Some fonts and math symbols are disabled. -security_level_limit_typography_svg = Some fonts, icons, math symbols, and images are disabled. -security_level_limit_media = Audio and video (HTML5 media), and WebGL are click-to-play. View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/ea9… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/ea9… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][base-browser-115.9.0esr-13.5-1] fixup! Bug 40925: Implemented the Security Level component
by richard (@richard) 26 Mar '24

26 Mar '24
richard pushed to branch base-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: 601bf763 by Henry Wilkes at 2024-03-26T17:54:31+00:00 fixup! Bug 40925: Implemented the Security Level component Bug 42214: Drop the securityLevel.properties file. - - - - - 1 changed file: - − browser/locales/en-US/chrome/browser/securityLevel.properties Changes: ===================================== browser/locales/en-US/chrome/browser/securityLevel.properties deleted ===================================== @@ -1,33 +0,0 @@ -# Generic terms -security_level = Security Level -security_level_standard = Standard -security_level_safer = Safer -security_level_safest = Safest -security_level_tooltip_standard = Security Level: Standard -security_level_tooltip_safer = Security Level: Safer -security_level_tooltip_safest = Security Level: Safest -# Shown only for custom level -security_level_custom = Custom -security_level_restore = Restore Defaults -security_level_learn_more = Learn more - -# Panel button that takes the user to the security level settings in -# about:preferences#privacy -security_level_open_settings = Settings… -security_level_change = Change… -security_level_standard_summary = All browser and website features are enabled. -security_level_safer_summary = Disables website features that are often dangerous, causing some sites to lose functionality. -security_level_safest_summary = Only allows website features required for static sites and basic services. These changes affect images, media, and scripts. -security_level_custom_heading = Custom security level configured -security_level_custom_summary = Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels. - -## Security level section in about:preferences#privacy -security_level_overview = Disable certain web features that can be used to attack your security and anonymity. -security_level_list_safer = At the safer setting: -security_level_list_safest = At the safest setting: -# Strings for descriptions -security_level_js_https_only = JavaScript is disabled on non-HTTPS sites. -security_level_js_disabled = JavaScript is disabled by default on all sites. -security_level_limit_typography = Some fonts and math symbols are disabled. -security_level_limit_typography_svg = Some fonts, icons, math symbols, and images are disabled. -security_level_limit_media = Audio and video (HTML5 media), and WebGL are click-to-play. View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/601bf76… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/601bf76… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.9.0esr-13.5-1] fixup! Bug 40925: Implemented the Security Level component
by richard (@richard) 26 Mar '24

26 Mar '24
richard pushed to branch tor-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: fec131fd by Henry Wilkes at 2024-03-26T17:50:00+00:00 fixup! Bug 40925: Implemented the Security Level component Bug 42214: Drop the securityLevel.properties file. - - - - - 1 changed file: - − browser/locales/en-US/chrome/browser/securityLevel.properties Changes: ===================================== browser/locales/en-US/chrome/browser/securityLevel.properties deleted ===================================== @@ -1,33 +0,0 @@ -# Generic terms -security_level = Security Level -security_level_standard = Standard -security_level_safer = Safer -security_level_safest = Safest -security_level_tooltip_standard = Security Level: Standard -security_level_tooltip_safer = Security Level: Safer -security_level_tooltip_safest = Security Level: Safest -# Shown only for custom level -security_level_custom = Custom -security_level_restore = Restore Defaults -security_level_learn_more = Learn more - -# Panel button that takes the user to the security level settings in -# about:preferences#privacy -security_level_open_settings = Settings… -security_level_change = Change… -security_level_standard_summary = All browser and website features are enabled. -security_level_safer_summary = Disables website features that are often dangerous, causing some sites to lose functionality. -security_level_safest_summary = Only allows website features required for static sites and basic services. These changes affect images, media, and scripts. -security_level_custom_heading = Custom security level configured -security_level_custom_summary = Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels. - -## Security level section in about:preferences#privacy -security_level_overview = Disable certain web features that can be used to attack your security and anonymity. -security_level_list_safer = At the safer setting: -security_level_list_safest = At the safest setting: -# Strings for descriptions -security_level_js_https_only = JavaScript is disabled on non-HTTPS sites. -security_level_js_disabled = JavaScript is disabled by default on all sites. -security_level_limit_typography = Some fonts and math symbols are disabled. -security_level_limit_typography_svg = Some fonts, icons, math symbols, and images are disabled. -security_level_limit_media = Audio and video (HTML5 media), and WebGL are click-to-play. View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/fec131f… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/fec131f… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.9.0esr-13.5-1] 3 commits: fixup! Bug 2176: Rebrand Firefox to TorBrowser
by richard (@richard) 26 Mar '24

26 Mar '24
richard pushed to branch tor-browser-115.9.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: 1ce353d9 by Henry Wilkes at 2024-03-26T17:47:47+00:00 fixup! Bug 2176: Rebrand Firefox to TorBrowser Bug 42466: Use the existing #trademark element from mozilla for Tor Browser&#39;s trademark statement. - - - - - 3cad3836 by Henry Wilkes at 2024-03-26T17:47:47+00:00 fixup! Tor Browser strings Bug 42466: Change trademark statement to remove &quot;onion logo&quot;, and move it to brand.ftl. - - - - - 37b97c98 by Henry Wilkes at 2024-03-26T17:47:47+00:00 fixup! Add TorStrings module for localization Bug 42466: Remove &quot;onion logo&quot; from trademark statement and move it to brand.ftl. - - - - - 4 changed files: - browser/base/content/aboutDialog.xhtml - browser/base/content/aboutDialogTor.css - browser/locales/en-US/browser/tor-browser.ftl - toolkit/torbutton/chrome/locale/en-US/branding/brand.ftl Changes: ===================================== browser/base/content/aboutDialog.xhtml ===================================== @@ -20,7 +20,7 @@ data-l10n-id="aboutDialog-title" #endif role="dialog" - aria-describedby="version distribution distributionId projectDesc helpDesc trademark trademarkTor" + aria-describedby="version distribution distributionId projectDesc helpDesc trademark" > #ifdef XP_MACOSX #include macWindow.inc.xhtml @@ -150,7 +150,6 @@ <label is="text-link" class="bottom-link" useoriginprincipal="true" href="about:license" data-l10n-id="about-dialog-browser-license-link"></label> </hbox> <description id="trademark" data-l10n-id="trademarkInfo"></description> - <description id="trademarkTor" data-l10n-id="about-dialog-trademark-statement"></description> </vbox> </html:div> ===================================== browser/base/content/aboutDialogTor.css ===================================== @@ -18,15 +18,10 @@ } #trademark { - display: none; -} - -#trademarkTor { font-size: xx-small; text-align: center; color: #999999; - margin-top: 10px; - margin-bottom: 10px; + margin-block: 10px; } #bottomBox > hbox:not(#newBottom) { ===================================== browser/locales/en-US/browser/tor-browser.ftl ===================================== @@ -323,10 +323,6 @@ about-dialog-grow-tor-network-link = Help the Tor Network Grow! # Link text for the Tor Browser license page (about:license). about-dialog-browser-license-link = Licensing Information -# "Tor" and "The Onion Logo" are trademark names, so should not be translated (not including the quote marks, which can be localized). -# "The Tor Project, Inc." is an organisation name. -about-dialog-trademark-statement = “Tor” and “The Onion Logo” are registered trademarks of The Tor Project, Inc. - ## New tor circuit. # Shown in the File menu. ===================================== toolkit/torbutton/chrome/locale/en-US/branding/brand.ftl ===================================== @@ -9,4 +9,6 @@ # remain unchanged across different versions (Nightly, Beta, etc.). -brand-product-name = Tor Browser -vendor-short-name = Tor Project -trademarkInfo = 'Tor' and the 'Onion Logo' are registered trademarks of the Tor Project, Inc. +# "Tor" is a trademark names, so should not be translated (not including the quote marks, which can be localized). +# "The Tor Project, Inc." is an organisation name. +trademarkInfo = “Tor” and the Tor logo are registered trademarks of The Tor Project, Inc. View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/570b6c… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/570b6c… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser-build][main] Bug 41110: Avoid Fontconfig warning about "ambiguous path"
by richard (@richard) 26 Mar '24

26 Mar '24
richard pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: c7092a88 by Rusty Bird at 2024-03-23T11:54:07+00:00 Bug 41110: Avoid Fontconfig warning about &quot;ambiguous path&quot; - - - - - 1 changed file: - projects/browser/Bundle-Data/linux/Data/fontconfig/fonts.conf Changes: ===================================== projects/browser/Bundle-Data/linux/Data/fontconfig/fonts.conf ===================================== @@ -39,7 +39,7 @@ PERFORMANCE OF THIS SOFTWARE. <!-- Font directory list --> - <dir>fonts</dir> + <dir prefix="cwd">fonts</dir> <!-- Accept deprecated 'mono' alias, replacing it with 'monospace' View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/c… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/c… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • ...
  • 18
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.