Dan Ballard pushed to branch tor-browser-128.11.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
1f3d54f3
by clairehurst at 2025-06-04T12:43:41+02:00
-
4c264ede
by clairehurst at 2025-06-04T12:43:41+02:00
-
80613d52
by clairehurst at 2025-06-04T12:43:42+02:00
18 changed files:
- mobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt
- mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/Settings.kt
- mobile/android/android-components/components/feature/search/src/main/java/mozilla/components/feature/search/SearchUseCases.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
- − mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/TorSecurityLevelFragment.kt
- − mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/SecurityLevel.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorConnectionAssistFragment.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevel.kt
- + mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevelFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
- + mobile/android/fenix/app/src/main/res/layout/fragment_tor_security_level_preferences.xml
- mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml
- mobile/android/fenix/app/src/main/res/values/preference_keys.xml
- mobile/android/fenix/app/src/main/res/values/torbrowser_strings.xml
- mobile/android/fenix/app/src/main/res/xml/preferences.xml
- − mobile/android/fenix/app/src/main/res/xml/tor_security_level_preferences.xml
Changes:
| ... | ... | @@ -1335,9 +1335,7 @@ class GeckoEngine( |
| 1335 | 1335 | override var torSecurityLevel: Int
|
| 1336 | 1336 | get() = runtime.settings.torSecurityLevel
|
| 1337 | 1337 | set(value) {
|
| 1338 | - value.let {
|
|
| 1339 | - runtime.settings.torSecurityLevel = it
|
|
| 1340 | - }
|
|
| 1338 | + runtime.settings.torSecurityLevel = value
|
|
| 1341 | 1339 | }
|
| 1342 | 1340 | |
| 1343 | 1341 | override var spoofEnglish: Boolean
|
| ... | ... | @@ -254,6 +254,12 @@ abstract class Settings { |
| 254 | 254 | |
| 255 | 255 | /**
|
| 256 | 256 | * Setting to control the current security level
|
| 257 | + *
|
|
| 258 | + * 4 -> STANDARD
|
|
| 259 | + *
|
|
| 260 | + * 2 -> SAFER
|
|
| 261 | + *
|
|
| 262 | + * 1 -> SAFEST
|
|
| 257 | 263 | */
|
| 258 | 264 | open var torSecurityLevel: Int by UnsupportedSetting()
|
| 259 | 265 |
| ... | ... | @@ -76,12 +76,7 @@ class SearchUseCases( |
| 76 | 76 | flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none(),
|
| 77 | 77 | additionalHeaders: Map<String, String>? = null,
|
| 78 | 78 | ) {
|
| 79 | - var securityLevel: Int
|
|
| 80 | - try {
|
|
| 81 | - securityLevel = settings?.torSecurityLevel ?: 0
|
|
| 82 | - } catch (e: UnsupportedSettingException) {
|
|
| 83 | - securityLevel = 0
|
|
| 84 | - }
|
|
| 79 | + val securityLevel : Int = settings!!.torSecurityLevel
|
|
| 85 | 80 | val searchUrl = searchEngine?.let {
|
| 86 | 81 | searchEngine.buildSearchUrl(searchTerms, securityLevel)
|
| 87 | 82 | } ?: store.state.search.selectedOrDefaultSearchEngine?.buildSearchUrl(searchTerms, securityLevel)
|
| ... | ... | @@ -172,12 +167,7 @@ class SearchUseCases( |
| 172 | 167 | flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none(),
|
| 173 | 168 | additionalHeaders: Map<String, String>? = null,
|
| 174 | 169 | ) {
|
| 175 | - var securityLevel: Int
|
|
| 176 | - try {
|
|
| 177 | - securityLevel = settings?.torSecurityLevel ?: 0
|
|
| 178 | - } catch (e: UnsupportedSettingException) {
|
|
| 179 | - securityLevel = 0
|
|
| 180 | - }
|
|
| 170 | + val securityLevel : Int = settings!!.torSecurityLevel
|
|
| 181 | 171 | val searchUrl = searchEngine?.let {
|
| 182 | 172 | searchEngine.buildSearchUrl(searchTerms, securityLevel)
|
| 183 | 173 | } ?: store.state.search.selectedOrDefaultSearchEngine?.buildSearchUrl(searchTerms, securityLevel)
|
| ... | ... | @@ -1439,6 +1439,15 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorAn |
| 1439 | 1439 | private const val PWA_RECENTLY_USED_THRESHOLD = DateUtils.DAY_IN_MILLIS * 30L
|
| 1440 | 1440 | }
|
| 1441 | 1441 | |
| 1442 | + fun restartApplication() {
|
|
| 1443 | + startActivity(
|
|
| 1444 | + Intent(applicationContext, HomeActivity::class.java).addFlags(
|
|
| 1445 | + Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK,
|
|
| 1446 | + ),
|
|
| 1447 | + )
|
|
| 1448 | + shutDown()
|
|
| 1449 | + }
|
|
| 1450 | + |
|
| 1442 | 1451 | fun shutDown() : Nothing {
|
| 1443 | 1452 | finishAndRemoveTask()
|
| 1444 | 1453 | exitProcess(0)
|
| ... | ... | @@ -157,7 +157,7 @@ class Core( |
| 157 | 157 | cookieBannerHandlingGlobalRules = context.settings().shouldEnableCookieBannerGlobalRules,
|
| 158 | 158 | cookieBannerHandlingGlobalRulesSubFrames = context.settings().shouldEnableCookieBannerGlobalRulesSubFrame,
|
| 159 | 159 | emailTrackerBlockingPrivateBrowsing = false,
|
| 160 | - torSecurityLevel = context.settings().torSecurityLevel().intRepresentation,
|
|
| 160 | + torSecurityLevel = context.settings().torSecurityLevel,
|
|
| 161 | 161 | spoofEnglish = context.settings().spoofEnglish,
|
| 162 | 162 | )
|
| 163 | 163 |
| ... | ... | @@ -13,6 +13,7 @@ import android.os.Build |
| 13 | 13 | import android.os.Bundle
|
| 14 | 14 | import android.os.Handler
|
| 15 | 15 | import android.os.Looper
|
| 16 | +import android.util.Log
|
|
| 16 | 17 | import android.view.LayoutInflater
|
| 17 | 18 | import android.view.WindowManager
|
| 18 | 19 | import android.widget.Toast
|
| ... | ... | @@ -67,7 +68,7 @@ import org.mozilla.fenix.ext.showToolbar |
| 67 | 68 | import org.mozilla.fenix.nimbus.FxNimbus
|
| 68 | 69 | import org.mozilla.fenix.perf.ProfilerViewModel
|
| 69 | 70 | import org.mozilla.fenix.settings.account.AccountUiView
|
| 70 | -import org.mozilla.fenix.tor.SecurityLevel
|
|
| 71 | +import org.mozilla.fenix.tor.TorSecurityLevel
|
|
| 71 | 72 | import org.mozilla.fenix.tor.QuickstartViewModel
|
| 72 | 73 | import org.mozilla.fenix.utils.Settings
|
| 73 | 74 | import kotlin.system.exitProcess
|
| ... | ... | @@ -353,7 +354,7 @@ class SettingsFragment : PreferenceFragmentCompat(), UserInteractionHandler { |
| 353 | 354 | SettingsFragmentDirections.actionSettingsFragmentToPrivateBrowsingFragment()
|
| 354 | 355 | }
|
| 355 | 356 | |
| 356 | - resources.getString(R.string.pref_key_tor_security_level_settings) -> {
|
|
| 357 | + resources.getString(R.string.pref_key_tor_security_level) -> {
|
|
| 357 | 358 | SettingsFragmentDirections.actionSettingsFragmentToTorSecurityLevelFragment()
|
| 358 | 359 | }
|
| 359 | 360 | |
| ... | ... | @@ -852,14 +853,14 @@ class SettingsFragment : PreferenceFragmentCompat(), UserInteractionHandler { |
| 852 | 853 | @VisibleForTesting
|
| 853 | 854 | internal fun setupSecurityLevelPreference() {
|
| 854 | 855 | val securityLevelPreference =
|
| 855 | - requirePreference<Preference>(R.string.pref_key_tor_security_level_settings)
|
|
| 856 | - securityLevelPreference.summary = context?.settings()?.torSecurityLevel()?.let {
|
|
| 857 | - when (it) {
|
|
| 858 | - SecurityLevel.STANDARD -> getString(R.string.tor_security_level_standard_option)
|
|
| 859 | - SecurityLevel.SAFER -> getString(R.string.tor_security_level_safer_option)
|
|
| 860 | - SecurityLevel.SAFEST -> getString(R.string.tor_security_level_safest_option)
|
|
| 856 | + requirePreference<Preference>(R.string.pref_key_tor_security_level)
|
|
| 857 | + securityLevelPreference.summary =
|
|
| 858 | + when (requireContext().settings().torSecurityLevel) {
|
|
| 859 | + TorSecurityLevel.STANDARD.level -> getString(R.string.tor_security_level_standard)
|
|
| 860 | + TorSecurityLevel.SAFER.level -> getString(R.string.tor_security_level_safer)
|
|
| 861 | + TorSecurityLevel.SAFEST.level -> getString(R.string.tor_security_level_safest)
|
|
| 862 | + else -> throw Exception("Unexpected TorSecurityLevel of ${requireContext().settings().torSecurityLevel}")
|
|
| 861 | 863 | }
|
| 862 | - }
|
|
| 863 | 864 | }
|
| 864 | 865 | |
| 865 | 866 | @VisibleForTesting
|
| 1 | -/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
| 2 | - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
| 3 | - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
| 4 | - |
|
| 5 | -package org.mozilla.fenix.settings
|
|
| 6 | - |
|
| 7 | -import android.os.Bundle
|
|
| 8 | -import androidx.preference.PreferenceFragmentCompat
|
|
| 9 | -import org.mozilla.fenix.R
|
|
| 10 | -import org.mozilla.fenix.ext.components
|
|
| 11 | -import org.mozilla.fenix.ext.settings
|
|
| 12 | -import org.mozilla.fenix.ext.showToolbar
|
|
| 13 | -import org.mozilla.fenix.tor.SecurityLevel
|
|
| 14 | -import org.mozilla.fenix.tor.SecurityLevelUtil
|
|
| 15 | -import org.mozilla.fenix.utils.view.GroupableRadioButton
|
|
| 16 | -import org.mozilla.fenix.utils.view.addToRadioGroup
|
|
| 17 | -import org.mozilla.fenix.utils.view.uncheckAll
|
|
| 18 | - |
|
| 19 | -/**
|
|
| 20 | - * Lets the user choose their security level
|
|
| 21 | - */
|
|
| 22 | -@Suppress("SpreadOperator")
|
|
| 23 | -class TorSecurityLevelFragment : PreferenceFragmentCompat() {
|
|
| 24 | - private val securityLevelRadioGroups = mutableListOf<GroupableRadioButton>()
|
|
| 25 | - private var previousSecurityLevel: SecurityLevel? = null
|
|
| 26 | - |
|
| 27 | - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
|
| 28 | - setPreferencesFromResource(R.xml.tor_security_level_preferences, rootKey)
|
|
| 29 | - |
|
| 30 | - val currentLevel: SecurityLevel? = context?.components?.let {
|
|
| 31 | - try {
|
|
| 32 | - SecurityLevelUtil.getSecurityLevelFromInt(
|
|
| 33 | - it.core.engine.settings.torSecurityLevel
|
|
| 34 | - )
|
|
| 35 | - } catch (e: IllegalStateException) {
|
|
| 36 | - // The default state is 0. If we get an invalid state then
|
|
| 37 | - // default to Standard (4).
|
|
| 38 | - SecurityLevel.STANDARD
|
|
| 39 | - }
|
|
| 40 | - }
|
|
| 41 | - |
|
| 42 | - if (currentLevel == null) {
|
|
| 43 | - throw IllegalStateException("context or Components is null.")
|
|
| 44 | - }
|
|
| 45 | - |
|
| 46 | - val radioSafer = bindSecurityLevelRadio(SecurityLevel.SAFER)
|
|
| 47 | - val radioSafest = bindSecurityLevelRadio(SecurityLevel.SAFEST)
|
|
| 48 | - val radioStandard = bindSecurityLevelRadio(SecurityLevel.STANDARD)
|
|
| 49 | - |
|
| 50 | - securityLevelRadioGroups.addAll(mutableListOf(radioSafer, radioSafest, radioStandard))
|
|
| 51 | - // `*` is Kotlin's "spread" operator, for expanding an Array as a vararg.
|
|
| 52 | - addToRadioGroup(*securityLevelRadioGroups.toTypedArray())
|
|
| 53 | - |
|
| 54 | - securityLevelRadioGroups.uncheckAll()
|
|
| 55 | - val securityLevelRadioButton = requirePreference<RadioButtonPreference>(currentLevel.preferenceKey)
|
|
| 56 | - // Cache this for later comparison in the OnPreferenceChangeListener
|
|
| 57 | - previousSecurityLevel = currentLevel
|
|
| 58 | - securityLevelRadioButton.setCheckedWithoutClickListener(true)
|
|
| 59 | - }
|
|
| 60 | - |
|
| 61 | - private fun bindSecurityLevelRadio(
|
|
| 62 | - level: SecurityLevel
|
|
| 63 | - ): RadioButtonPreference {
|
|
| 64 | - val radio = requirePreference<RadioButtonPreference>(level.preferenceKey)
|
|
| 65 | - |
|
| 66 | - radio.summary = getString(level.contentDescriptionRes)
|
|
| 67 | - |
|
| 68 | - radio.apply {
|
|
| 69 | - setOnPreferenceChangeListener<Boolean> { preference, isChecked ->
|
|
| 70 | - if (isChecked && (previousSecurityLevel!! != level)) {
|
|
| 71 | - preference.context.components.core.engine.settings.torSecurityLevel =
|
|
| 72 | - level.intRepresentation
|
|
| 73 | - previousSecurityLevel = level
|
|
| 74 | - }
|
|
| 75 | - true
|
|
| 76 | - }
|
|
| 77 | - }
|
|
| 78 | - |
|
| 79 | - return radio
|
|
| 80 | - }
|
|
| 81 | -} |
| 1 | -/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
| 2 | - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
| 3 | - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
| 4 | - |
|
| 5 | -package org.mozilla.fenix.tor
|
|
| 6 | - |
|
| 7 | -import android.os.Parcelable
|
|
| 8 | -import androidx.annotation.StringRes
|
|
| 9 | -import kotlinx.parcelize.Parcelize
|
|
| 10 | -import org.mozilla.fenix.R
|
|
| 11 | - |
|
| 12 | - |
|
| 13 | -const val SECURITY_LEVEL_STANDARD = 4
|
|
| 14 | -const val SECURITY_LEVEL_SAFER = 2
|
|
| 15 | -const val SECURITY_LEVEL_SAFEST = 1
|
|
| 16 | - |
|
| 17 | -@Parcelize
|
|
| 18 | -enum class SecurityLevel(
|
|
| 19 | - @StringRes val preferenceKey: Int,
|
|
| 20 | - @StringRes val contentDescriptionRes: Int,
|
|
| 21 | - val intRepresentation: Int
|
|
| 22 | -) : Parcelable {
|
|
| 23 | - |
|
| 24 | - STANDARD(
|
|
| 25 | - preferenceKey = R.string.pref_key_tor_security_level_standard_option,
|
|
| 26 | - contentDescriptionRes = R.string.tor_security_level_standard_description,
|
|
| 27 | - intRepresentation = SECURITY_LEVEL_STANDARD
|
|
| 28 | - ),
|
|
| 29 | - SAFER(
|
|
| 30 | - preferenceKey = R.string.pref_key_tor_security_level_safer_option,
|
|
| 31 | - contentDescriptionRes = R.string.tor_security_level_safer_description,
|
|
| 32 | - intRepresentation = SECURITY_LEVEL_SAFER
|
|
| 33 | - ),
|
|
| 34 | - SAFEST(
|
|
| 35 | - preferenceKey = R.string.pref_key_tor_security_level_safest_option,
|
|
| 36 | - contentDescriptionRes = R.string.tor_security_level_safest_description,
|
|
| 37 | - intRepresentation = SECURITY_LEVEL_SAFEST
|
|
| 38 | - );
|
|
| 39 | - |
|
| 40 | - |
|
| 41 | - |
|
| 42 | -}
|
|
| 43 | - |
|
| 44 | -object SecurityLevelUtil {
|
|
| 45 | - fun getSecurityLevelFromInt(level: Int): SecurityLevel {
|
|
| 46 | - return when (level) {
|
|
| 47 | - SECURITY_LEVEL_STANDARD -> SecurityLevel.STANDARD
|
|
| 48 | - SECURITY_LEVEL_SAFER -> SecurityLevel.SAFER
|
|
| 49 | - SECURITY_LEVEL_SAFEST -> SecurityLevel.SAFEST
|
|
| 50 | - else -> throw IllegalStateException("Security Level $level is not valid")
|
|
| 51 | - }
|
|
| 52 | - }
|
|
| 53 | -} |
| ... | ... | @@ -343,7 +343,7 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 343 | 343 | if (screen.torBootstrapButton2ShouldOpenSettings) {
|
| 344 | 344 | openTorConnectionSettings()
|
| 345 | 345 | } else if (screen.torBootstrapButton2ShouldRestartApp) {
|
| 346 | - restartApplication()
|
|
| 346 | + (requireActivity() as HomeActivity).restartApplication()
|
|
| 347 | 347 | } else {
|
| 348 | 348 | torConnectionAssistViewModel.cancelTorBootstrap()
|
| 349 | 349 | }
|
| ... | ... | @@ -404,15 +404,6 @@ class TorConnectionAssistFragment : Fragment(), UserInteractionHandler { |
| 404 | 404 | openSettings(requireContext().getString(R.string.pref_key_connection))
|
| 405 | 405 | }
|
| 406 | 406 | |
| 407 | - private fun restartApplication() {
|
|
| 408 | - startActivity(
|
|
| 409 | - Intent(requireContext(), HomeActivity::class.java).addFlags(
|
|
| 410 | - Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK,
|
|
| 411 | - ),
|
|
| 412 | - )
|
|
| 413 | - Runtime.getRuntime().exit(0)
|
|
| 414 | - }
|
|
| 415 | - |
|
| 416 | 407 | override fun onBackPressed(): Boolean {
|
| 417 | 408 | torConnectionAssistViewModel.handleBackButtonPressed(requireActivity() as HomeActivity)
|
| 418 | 409 | return true
|
| 1 | +/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
| 2 | + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
| 3 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
| 4 | + |
|
| 5 | +package org.mozilla.fenix.tor
|
|
| 6 | + |
|
| 7 | +import android.os.Parcelable
|
|
| 8 | +import kotlinx.parcelize.Parcelize
|
|
| 9 | + |
|
| 10 | +@Parcelize
|
|
| 11 | +enum class TorSecurityLevel(val level: Int) : Parcelable {
|
|
| 12 | + STANDARD(4), SAFER(2), SAFEST(1)
|
|
| 13 | +} |
| 1 | +/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
| 2 | + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
| 3 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
| 4 | + |
|
| 5 | +package org.mozilla.fenix.tor
|
|
| 6 | + |
|
| 7 | +import android.content.Context
|
|
| 8 | +import android.os.Bundle
|
|
| 9 | +import android.util.Log
|
|
| 10 | +import android.view.LayoutInflater
|
|
| 11 | +import android.view.View
|
|
| 12 | +import android.view.ViewGroup
|
|
| 13 | +import android.widget.Toast
|
|
| 14 | +import androidx.appcompat.content.res.AppCompatResources
|
|
| 15 | +import androidx.fragment.app.Fragment
|
|
| 16 | +import org.mozilla.fenix.HomeActivity
|
|
| 17 | +import org.mozilla.fenix.R
|
|
| 18 | +import org.mozilla.fenix.ext.components
|
|
| 19 | +import org.mozilla.fenix.databinding.FragmentTorSecurityLevelPreferencesBinding
|
|
| 20 | +import androidx.core.content.edit
|
|
| 21 | + |
|
| 22 | +class TorSecurityLevelFragment : Fragment() {
|
|
| 23 | + private var _binding: FragmentTorSecurityLevelPreferencesBinding? = null
|
|
| 24 | + private val binding get() = _binding!!
|
|
| 25 | + |
|
| 26 | + private val tag = "TorSecurityLevelFrag"
|
|
| 27 | + |
|
| 28 | + override fun onCreateView(
|
|
| 29 | + inflater: LayoutInflater,
|
|
| 30 | + container: ViewGroup?,
|
|
| 31 | + savedInstanceState: Bundle?,
|
|
| 32 | + ): View {
|
|
| 33 | + _binding = FragmentTorSecurityLevelPreferencesBinding.inflate(
|
|
| 34 | + inflater, container, false,
|
|
| 35 | + )
|
|
| 36 | + |
|
| 37 | + return binding.root
|
|
| 38 | + }
|
|
| 39 | + |
|
| 40 | + override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
| 41 | + super.onViewCreated(view, savedInstanceState)
|
|
| 42 | + |
|
| 43 | + binding.description.text = getString(R.string.tor_security_level_warning, getString(R.string.app_name))
|
|
| 44 | + |
|
| 45 | + updateSaveAndRestartButtonUI()
|
|
| 46 | + |
|
| 47 | + val currentLevel: Int = requireContext().components.core.engine.settings.torSecurityLevel
|
|
| 48 | + |
|
| 49 | + when (currentLevel) {
|
|
| 50 | + TorSecurityLevel.STANDARD.level -> {
|
|
| 51 | + binding.standardPreference.text =
|
|
| 52 | + getString(R.string.tor_security_level_standard_current_level)
|
|
| 53 | + binding.securityLevelRadioGroup.check(binding.standardPreference.id)
|
|
| 54 | + }
|
|
| 55 | + |
|
| 56 | + TorSecurityLevel.SAFER.level -> {
|
|
| 57 | + binding.saferPreference.text =
|
|
| 58 | + getString(R.string.tor_security_level_safer_current_level)
|
|
| 59 | + binding.securityLevelRadioGroup.check(binding.saferPreference.id)
|
|
| 60 | + }
|
|
| 61 | + |
|
| 62 | + TorSecurityLevel.SAFEST.level -> {
|
|
| 63 | + binding.safestPreference.text =
|
|
| 64 | + getString(R.string.tor_security_level_safest_current_level)
|
|
| 65 | + binding.securityLevelRadioGroup.check(binding.safestPreference.id)
|
|
| 66 | + }
|
|
| 67 | + }
|
|
| 68 | + |
|
| 69 | + binding.securityLevelRadioGroup.setOnCheckedChangeListener { _, checkedId ->
|
|
| 70 | + binding.saveAndRestartButton.isEnabled = when (checkedId) {
|
|
| 71 | + binding.standardPreference.id -> currentLevel != TorSecurityLevel.STANDARD.level
|
|
| 72 | + binding.saferPreference.id -> currentLevel != TorSecurityLevel.SAFER.level
|
|
| 73 | + binding.safestPreference.id -> currentLevel != TorSecurityLevel.SAFEST.level
|
|
| 74 | + else -> throw Exception("unexpected checkedID of $checkedId")
|
|
| 75 | + }
|
|
| 76 | + |
|
| 77 | + updateSaveAndRestartButtonUI()
|
|
| 78 | + }
|
|
| 79 | + |
|
| 80 | + binding.saveAndRestartButton.setOnClickListener {
|
|
| 81 | + |
|
| 82 | + Toast.makeText(
|
|
| 83 | + requireContext(),
|
|
| 84 | + R.string.tor_security_level_restarting,
|
|
| 85 | + Toast.LENGTH_SHORT,
|
|
| 86 | + ).show()
|
|
| 87 | + |
|
| 88 | + val selectedSecurityLevel: Int =
|
|
| 89 | + when (binding.securityLevelRadioGroup.checkedRadioButtonId) {
|
|
| 90 | + binding.standardPreference.id -> TorSecurityLevel.STANDARD.level
|
|
| 91 | + binding.saferPreference.id -> TorSecurityLevel.SAFER.level
|
|
| 92 | + binding.safestPreference.id -> TorSecurityLevel.SAFEST.level
|
|
| 93 | + else -> throw Exception("Unexpected checkedRadioButtonId of ${binding.securityLevelRadioGroup.checkedRadioButtonId}")
|
|
| 94 | + }
|
|
| 95 | + |
|
| 96 | + requireContext().components.core.geckoRuntime.settings.torSecurityLevel = selectedSecurityLevel
|
|
| 97 | + |
|
| 98 | + requireActivity().getSharedPreferences("fenix_preferences", Context.MODE_PRIVATE).edit(
|
|
| 99 | + commit = true,
|
|
| 100 | + ) {
|
|
| 101 | + putInt(
|
|
| 102 | + requireContext().getString(R.string.pref_key_tor_security_level),
|
|
| 103 | + selectedSecurityLevel,
|
|
| 104 | + )
|
|
| 105 | + }
|
|
| 106 | + |
|
| 107 | + Thread.sleep(1000)
|
|
| 108 | + |
|
| 109 | + (requireActivity() as HomeActivity).restartApplication()
|
|
| 110 | + }
|
|
| 111 | + |
|
| 112 | + binding.cancelButton.setOnClickListener {
|
|
| 113 | + requireActivity().onBackPressed()
|
|
| 114 | + }
|
|
| 115 | + }
|
|
| 116 | + |
|
| 117 | + private fun updateSaveAndRestartButtonUI() {
|
|
| 118 | + binding.saveAndRestartButton.apply {
|
|
| 119 | + if (binding.saveAndRestartButton.isEnabled) {
|
|
| 120 | + backgroundTintList = AppCompatResources.getColorStateList(
|
|
| 121 | + requireContext(),
|
|
| 122 | + R.color.connect_button_purple,
|
|
| 123 | + )
|
|
| 124 | + setTextColor(
|
|
| 125 | + AppCompatResources.getColorStateList(
|
|
| 126 | + requireContext(),
|
|
| 127 | + R.color.photonLightGrey05,
|
|
| 128 | + ),
|
|
| 129 | + )
|
|
| 130 | + } else {
|
|
| 131 | + backgroundTintList = AppCompatResources.getColorStateList(
|
|
| 132 | + requireContext(),
|
|
| 133 | + R.color.disabled_connect_button_purple,
|
|
| 134 | + )
|
|
| 135 | + setTextColor(
|
|
| 136 | + AppCompatResources.getColorStateList(
|
|
| 137 | + requireContext(),
|
|
| 138 | + R.color.disabled_text_gray_purple,
|
|
| 139 | + ),
|
|
| 140 | + )
|
|
| 141 | + }
|
|
| 142 | + }
|
|
| 143 | + }
|
|
| 144 | +} |
| ... | ... | @@ -52,7 +52,8 @@ import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener |
| 52 | 52 | import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_ALL
|
| 53 | 53 | import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_AUDIBLE
|
| 54 | 54 | import org.mozilla.fenix.wallpapers.Wallpaper
|
| 55 | -import org.mozilla.fenix.tor.SecurityLevel
|
|
| 55 | +import org.mozilla.fenix.settings.SettingsFragment
|
|
| 56 | +import org.mozilla.fenix.tor.TorSecurityLevel
|
|
| 56 | 57 | import java.security.InvalidParameterException
|
| 57 | 58 | import java.util.UUID
|
| 58 | 59 | |
| ... | ... | @@ -299,31 +300,55 @@ class Settings(private val appContext: Context) : PreferencesHolder { |
| 299 | 300 | false,
|
| 300 | 301 | )
|
| 301 | 302 | |
| 302 | - var standardSecurityLevel by booleanPreference(
|
|
| 303 | - appContext.getPreferenceKey(SecurityLevel.STANDARD.preferenceKey),
|
|
| 304 | - default = true
|
|
| 303 | + private var oldStandardSecurityLevel by booleanPreference(
|
|
| 304 | + appContext.getPreferenceKey(R.string.pref_key_tor_security_level_standard_option),
|
|
| 305 | + default = false
|
|
| 305 | 306 | )
|
| 306 | 307 | |
| 307 | - var saferSecurityLevel by booleanPreference(
|
|
| 308 | - appContext.getPreferenceKey(SecurityLevel.SAFER.preferenceKey),
|
|
| 308 | + private var oldSaferSecurityLevel by booleanPreference(
|
|
| 309 | + appContext.getPreferenceKey(R.string.pref_key_tor_security_level_safer_option),
|
|
| 309 | 310 | default = false
|
| 310 | 311 | )
|
| 311 | 312 | |
| 312 | - var safestSecurityLevel by booleanPreference(
|
|
| 313 | - appContext.getPreferenceKey(SecurityLevel.SAFEST.preferenceKey),
|
|
| 313 | + private var oldSafestSecurityLevel by booleanPreference(
|
|
| 314 | + appContext.getPreferenceKey(R.string.pref_key_tor_security_level_safest_option),
|
|
| 314 | 315 | default = false
|
| 315 | 316 | )
|
| 316 | 317 | |
| 317 | - // torSecurityLevel is defined as the first |true| preference,
|
|
| 318 | - // beginning at the safest level.
|
|
| 319 | - // If multiple preferences are true, then that is a bug and the
|
|
| 320 | - // highest |true| security level is chosen.
|
|
| 321 | - // Standard is the default level.
|
|
| 322 | - fun torSecurityLevel(): SecurityLevel = when {
|
|
| 323 | - safestSecurityLevel -> SecurityLevel.SAFEST
|
|
| 324 | - saferSecurityLevel -> SecurityLevel.SAFER
|
|
| 325 | - standardSecurityLevel -> SecurityLevel.STANDARD
|
|
| 326 | - else -> SecurityLevel.STANDARD
|
|
| 318 | + /**
|
|
| 319 | + * Backing property that should used only for the [SettingsFragment] UI
|
|
| 320 | + *
|
|
| 321 | + * 4 -> STANDARD
|
|
| 322 | + *
|
|
| 323 | + * 2 -> SAFER
|
|
| 324 | + *
|
|
| 325 | + * 1 -> SAFEST
|
|
| 326 | + */
|
|
| 327 | + var torSecurityLevel by intPreference(
|
|
| 328 | + appContext.getPreferenceKey(R.string.pref_key_tor_security_level),
|
|
| 329 | + migrateTorSecurityLevel() ?: 4,
|
|
| 330 | + )
|
|
| 331 | + |
|
| 332 | + /**
|
|
| 333 | + * Remove in 15.0 release.
|
|
| 334 | + */
|
|
| 335 | + private fun migrateTorSecurityLevel(): Int? {
|
|
| 336 | + return when {
|
|
| 337 | + oldSafestSecurityLevel -> {
|
|
| 338 | + TorSecurityLevel.SAFEST.level
|
|
| 339 | + }
|
|
| 340 | + oldSaferSecurityLevel -> {
|
|
| 341 | + TorSecurityLevel.SAFER.level
|
|
| 342 | + }
|
|
| 343 | + oldStandardSecurityLevel -> {
|
|
| 344 | + TorSecurityLevel.STANDARD.level
|
|
| 345 | + }
|
|
| 346 | + else -> null
|
|
| 347 | + }.also {
|
|
| 348 | + oldSafestSecurityLevel = false
|
|
| 349 | + oldSaferSecurityLevel = false
|
|
| 350 | + oldStandardSecurityLevel = false
|
|
| 351 | + }
|
|
| 327 | 352 | }
|
| 328 | 353 | |
| 329 | 354 | var spoofEnglish by booleanPreference(
|
| 1 | +<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
|
|
| 2 | + - License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
| 3 | + - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
|
| 4 | +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
| 5 | + xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
| 6 | + android:layout_width="match_parent"
|
|
| 7 | + android:layout_height="match_parent">
|
|
| 8 | + |
|
| 9 | + <TextView
|
|
| 10 | + android:id="@+id/description"
|
|
| 11 | + android:layout_width="match_parent"
|
|
| 12 | + android:layout_height="wrap_content"
|
|
| 13 | + android:lineSpacingExtra="6dp"
|
|
| 14 | + android:paddingHorizontal="24dp"
|
|
| 15 | + android:paddingVertical="16dp"
|
|
| 16 | + android:text="@string/tor_security_level_warning"
|
|
| 17 | + android:textColor="@color/photonLightGrey40"
|
|
| 18 | + android:textSize="14sp"
|
|
| 19 | + app:layout_constraintTop_toTopOf="parent" />
|
|
| 20 | + |
|
| 21 | + <RadioGroup
|
|
| 22 | + android:id="@+id/security_level_radio_group"
|
|
| 23 | + android:layout_width="match_parent"
|
|
| 24 | + android:layout_height="wrap_content"
|
|
| 25 | + android:layout_marginHorizontal="16dp"
|
|
| 26 | + app:layout_constraintTop_toBottomOf="@+id/description">
|
|
| 27 | + |
|
| 28 | + <RadioButton
|
|
| 29 | + android:id="@+id/standard_preference"
|
|
| 30 | + android:layout_width="match_parent"
|
|
| 31 | + android:layout_height="wrap_content"
|
|
| 32 | + android:text="@string/tor_security_level_standard"
|
|
| 33 | + android:textColor="@color/photonLightGrey05"
|
|
| 34 | + android:textSize="16sp" />
|
|
| 35 | + |
|
| 36 | + <TextView
|
|
| 37 | + android:id="@+id/standard_preference_description"
|
|
| 38 | + android:layout_width="match_parent"
|
|
| 39 | + android:layout_height="wrap_content"
|
|
| 40 | + android:layout_marginStart="32dp"
|
|
| 41 | + android:text="@string/tor_security_level_standard_description"
|
|
| 42 | + android:textColor="@color/photonLightGrey40" />
|
|
| 43 | + |
|
| 44 | + <RadioButton
|
|
| 45 | + android:id="@+id/safer_preference"
|
|
| 46 | + android:layout_width="match_parent"
|
|
| 47 | + android:layout_height="wrap_content"
|
|
| 48 | + android:text="@string/tor_security_level_safer"
|
|
| 49 | + android:textColor="@color/photonLightGrey05"
|
|
| 50 | + android:textSize="16sp" />
|
|
| 51 | + |
|
| 52 | + <TextView
|
|
| 53 | + android:id="@+id/safer_preference_description"
|
|
| 54 | + android:layout_width="match_parent"
|
|
| 55 | + android:layout_height="wrap_content"
|
|
| 56 | + android:layout_marginStart="32dp"
|
|
| 57 | + android:text="@string/tor_security_level_safer_description"
|
|
| 58 | + android:textColor="@color/photonLightGrey40" />
|
|
| 59 | + |
|
| 60 | + <RadioButton
|
|
| 61 | + android:id="@+id/safest_preference"
|
|
| 62 | + android:layout_width="match_parent"
|
|
| 63 | + android:layout_height="wrap_content"
|
|
| 64 | + android:text="@string/tor_security_level_safest"
|
|
| 65 | + android:textColor="@color/photonLightGrey05"
|
|
| 66 | + android:textSize="16sp" />
|
|
| 67 | + |
|
| 68 | + <TextView
|
|
| 69 | + android:id="@+id/safest_preference_description"
|
|
| 70 | + android:layout_width="match_parent"
|
|
| 71 | + android:layout_height="wrap_content"
|
|
| 72 | + android:layout_marginStart="32dp"
|
|
| 73 | + android:text="@string/tor_security_level_safest_description"
|
|
| 74 | + android:textColor="@color/photonLightGrey40" />
|
|
| 75 | + </RadioGroup>
|
|
| 76 | + |
|
| 77 | + <Button
|
|
| 78 | + android:id="@+id/save_and_restart_button"
|
|
| 79 | + android:layout_width="wrap_content"
|
|
| 80 | + android:layout_height="wrap_content"
|
|
| 81 | + android:layout_marginStart="24dp"
|
|
| 82 | + android:layout_marginEnd="24dp"
|
|
| 83 | + android:layout_marginBottom="8dp"
|
|
| 84 | + android:background="@drawable/rounded_corners"
|
|
| 85 | + android:backgroundTint="@color/connect_button_purple"
|
|
| 86 | + android:enabled="false"
|
|
| 87 | + android:minWidth="360dp"
|
|
| 88 | + android:text="@string/tor_security_level_save_and_restart_tor_browser"
|
|
| 89 | + android:textAlignment="center"
|
|
| 90 | + android:textAllCaps="false"
|
|
| 91 | + android:textColor="@color/photonLightGrey05"
|
|
| 92 | + android:textSize="14sp"
|
|
| 93 | + android:textStyle="bold"
|
|
| 94 | + app:layout_constraintBottom_toTopOf="@id/cancel_button"
|
|
| 95 | + app:layout_constraintEnd_toEndOf="parent"
|
|
| 96 | + app:layout_constraintStart_toStartOf="parent" />
|
|
| 97 | + |
|
| 98 | + <Button
|
|
| 99 | + android:id="@+id/cancel_button"
|
|
| 100 | + android:layout_width="wrap_content"
|
|
| 101 | + android:layout_height="wrap_content"
|
|
| 102 | + android:layout_marginStart="24dp"
|
|
| 103 | + android:layout_marginEnd="24dp"
|
|
| 104 | + android:layout_marginBottom="8dp"
|
|
| 105 | + android:background="@drawable/rounded_corners"
|
|
| 106 | + android:backgroundTint="@color/configure_connection_button_white"
|
|
| 107 | + android:minWidth="360dp"
|
|
| 108 | + android:text="@string/btn_cancel"
|
|
| 109 | + android:textAlignment="center"
|
|
| 110 | + android:textAllCaps="false"
|
|
| 111 | + android:textColor="@color/photonDarkGrey90"
|
|
| 112 | + android:textSize="14sp"
|
|
| 113 | + android:textStyle="bold"
|
|
| 114 | + app:layout_constraintBottom_toBottomOf="parent"
|
|
| 115 | + app:layout_constraintEnd_toEndOf="parent"
|
|
| 116 | + app:layout_constraintStart_toStartOf="parent" />
|
|
| 117 | +</androidx.constraintlayout.widget.ConstraintLayout> |
| ... | ... | @@ -907,7 +907,7 @@ |
| 907 | 907 | android:label="@string/preferences_customize" />
|
| 908 | 908 | <fragment
|
| 909 | 909 | android:id="@+id/torSecurityLevelFragment"
|
| 910 | - android:name="org.mozilla.fenix.settings.TorSecurityLevelFragment"
|
|
| 910 | + android:name="org.mozilla.fenix.tor.TorSecurityLevelFragment"
|
|
| 911 | 911 | android:label="@string/preferences_tor_security_level_options" />
|
| 912 | 912 | <fragment
|
| 913 | 913 | android:id="@+id/privateBrowsingFragment"
|
| ... | ... | @@ -406,6 +406,9 @@ |
| 406 | 406 | <string name="pref_key_https_everywhere_removed" translatable="false">pref_key_https_everywhere_removed</string>
|
| 407 | 407 | |
| 408 | 408 | <!-- Security Level Settings -->
|
| 409 | + <string name="pref_key_tor_security_level" translatable="false">pref_key_tor_security_level</string>
|
|
| 410 | + |
|
| 411 | + <!-- Deprecated Security Level Settings -->
|
|
| 409 | 412 | <string name="pref_key_tor_security_level_settings" translatable="false">pref_key_tor_security_level_settings</string>
|
| 410 | 413 | <string name="pref_key_tor_security_level_standard_option" translatable="false">pref_key_tor_security_level_standard_option</string>
|
| 411 | 414 | <string name="pref_key_tor_security_level_safer_option" translatable="false">pref_key_tor_security_level_safer_option</string>
|
| ... | ... | @@ -36,12 +36,19 @@ |
| 36 | 36 | <string name="preferences_tor_security_level_options">Security Level</string>
|
| 37 | 37 | |
| 38 | 38 | <!-- Description of security levels -->
|
| 39 | - <string name="tor_security_level_standard_option">Standard</string>
|
|
| 39 | + <!-- %s will be replaced with the localised application name, such as "Tor Browser". -->
|
|
| 40 | + <string name="tor_security_level_warning">You will need to restart %s to apply any changes. This will close all tabs.</string>
|
|
| 41 | + <string name="tor_security_level_standard">Standard</string>
|
|
| 42 | + <string name="tor_security_level_standard_current_level">Standard (current level)</string>
|
|
| 40 | 43 | <string name="tor_security_level_standard_description">All Tor Browser and website features are enabled.</string>
|
| 41 | - <string name="tor_security_level_safer_option">Safer</string>
|
|
| 44 | + <string name="tor_security_level_safer">Safer</string>
|
|
| 45 | + <string name="tor_security_level_safer_current_level">Safer (current level)</string>
|
|
| 42 | 46 | <string name="tor_security_level_safer_description">Disable website features that are often dangerous, causing some sites to lose functionality.</string>
|
| 43 | - <string name="tor_security_level_safest_option">Safest</string>
|
|
| 47 | + <string name="tor_security_level_safest">Safest</string>
|
|
| 48 | + <string name="tor_security_level_safest_current_level">Safest (current level)</string>
|
|
| 44 | 49 | <string name="tor_security_level_safest_description">Only allow website features required for static sites and basic services. These changes affect images, media, and scripts.</string>
|
| 50 | + <string name="tor_security_level_save_and_restart_tor_browser">Save and restart</string>
|
|
| 51 | + <string name="tor_security_level_restarting">Restarting</string>
|
|
| 45 | 52 | |
| 46 | 53 | <string name="btn_cancel">Cancel</string>
|
| 47 | 54 |
| ... | ... | @@ -103,7 +103,7 @@ |
| 103 | 103 | android:layout="@layout/preference_category_no_icon_style">
|
| 104 | 104 | |
| 105 | 105 | <androidx.preference.Preference
|
| 106 | - android:key="@string/pref_key_tor_security_level_settings"
|
|
| 106 | + android:key="@string/pref_key_tor_security_level"
|
|
| 107 | 107 | app:iconSpaceReserved="false"
|
| 108 | 108 | android:title="@string/preferences_tor_security_level_options" />
|
| 109 | 109 |
| 1 | -<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
|
|
| 2 | - - License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
| 3 | - - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
|
| 4 | -<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
|
| 5 | - xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
| 6 | - <org.mozilla.fenix.settings.RadioButtonPreference
|
|
| 7 | - android:defaultValue="true"
|
|
| 8 | - android:key="@string/pref_key_tor_security_level_standard_option"
|
|
| 9 | - android:summary="@string/tor_security_level_standard_description"
|
|
| 10 | - android:title="@string/tor_security_level_standard_option" />
|
|
| 11 | - <org.mozilla.fenix.settings.RadioButtonPreference
|
|
| 12 | - android:defaultValue="false"
|
|
| 13 | - android:key="@string/pref_key_tor_security_level_safer_option"
|
|
| 14 | - android:summary="@string/tor_security_level_safer_description"
|
|
| 15 | - android:title="@string/tor_security_level_safer_option" />
|
|
| 16 | - <org.mozilla.fenix.settings.RadioButtonPreference
|
|
| 17 | - android:defaultValue="false"
|
|
| 18 | - android:key="@string/pref_key_tor_security_level_safest_option"
|
|
| 19 | - android:summary="@string/tor_security_level_safest_description"
|
|
| 20 | - android:title="@string/tor_security_level_safest_option" />
|
|
| 21 | -</androidx.preference.PreferenceScreen> |