tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit cc616b89abefe70d94150f64036441e30225f53a
parent 265dbba6a0b0a04f2123a2008d7fa9b8308c5d27
Author: Matthew Finkel <sysrqb@torproject.org>
Date:   Mon, 14 Sep 2020 03:48:05 +0000

TB 40026 [android]: Implement Security Level settings on Android.

Originally, fenix#40026.

Diffstat:
Mmobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt | 7+++++++
Mmobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/Settings.kt | 12++++++++++++
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt | 1+
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt | 20++++++++++++++++++++
Amobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevel.kt | 13+++++++++++++
Amobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevelFragment.kt | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Amobile/android/fenix/app/src/main/res/layout/fragment_tor_security_level_preferences.xml | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmobile/android/fenix/app/src/main/res/navigation/nav_graph.xml | 14++++++++++++++
Mmobile/android/fenix/app/src/main/res/values/preference_keys.xml | 9+++++++++
Mmobile/android/fenix/app/src/main/res/xml/preferences.xml | 5+++++
Mmobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorAndroidIntegration.java | 3+++
Mtoolkit/modules/TorAndroidIntegration.sys.mjs | 17+++++++++++++++++
13 files changed, 417 insertions(+), 0 deletions(-)

diff --git a/mobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt b/mobile/android/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt @@ -1626,6 +1626,12 @@ class GeckoEngine( value?.let { runtime.settings.setBaselineFingerprintingProtectionOverrides(it) } } + override var torSecurityLevel: Int + get() = runtime.settings.torSecurityLevel + set(value) { + runtime.settings.torSecurityLevel = value + } + override var spoofEnglish: Boolean get() = runtime.settings.spoofEnglish set(value) { @@ -1729,6 +1735,7 @@ class GeckoEngine( this.userCharacteristicPingCurrentVersion = it.userCharacteristicPingCurrentVersion this.baselineFingerprintingProtection = it.baselineFingerprintingProtection this.baselineFingerprintingProtectionOverrides = it.baselineFingerprintingProtectionOverrides + this.torSecurityLevel = it.torSecurityLevel this.spoofEnglish = it.spoofEnglish this.webContentIsolationStrategy = it.webContentIsolationStrategy this.fetchPriorityEnabled = it.fetchPriorityEnabled diff --git a/mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/Settings.kt b/mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/Settings.kt @@ -300,6 +300,17 @@ abstract class Settings { */ open var userCharacteristicPingCurrentVersion: Int by UnsupportedSetting() + /** + * Setting to control the current security level + * + * 4 -> STANDARD + * + * 2 -> SAFER + * + * 1 -> SAFEST + */ + open var torSecurityLevel: Int by UnsupportedSetting() + open var spoofEnglish: Boolean by UnsupportedSetting() /** @@ -451,6 +462,7 @@ data class DefaultSettings( override var queryParameterStrippingStripList: String = "", override var emailTrackerBlockingPrivateBrowsing: Boolean = false, override var userCharacteristicPingCurrentVersion: Int = 0, + override var torSecurityLevel: Int = 4, override var spoofEnglish: Boolean = false, override var webContentIsolationStrategy: WebContentIsolationStrategy? = WebContentIsolationStrategy.ISOLATE_HIGH_VALUE, diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -182,6 +182,7 @@ class Core( cookieBannerHandlingGlobalRulesSubFrames = context.settings().shouldEnableCookieBannerGlobalRulesSubFrame, emailTrackerBlockingPrivateBrowsing = false, userCharacteristicPingCurrentVersion = FxNimbus.features.userCharacteristics.value().currentVersion, + torSecurityLevel = context.settings().torSecurityLevel, spoofEnglish = context.settings().spoofEnglish, getDesktopMode = { store.state.desktopMode diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -9,6 +9,7 @@ import android.content.DialogInterface import android.os.Bundle import android.os.Handler import android.os.Looper +import android.util.Log import android.view.LayoutInflater import android.view.View import android.widget.Toast @@ -71,6 +72,7 @@ import org.mozilla.fenix.perf.ProfilerViewModelFactory import org.mozilla.fenix.settings.account.AccountUiView import org.mozilla.fenix.snackbar.FenixSnackbarDelegate import org.mozilla.fenix.snackbar.SnackbarBinding +import org.mozilla.fenix.tor.TorSecurityLevel import org.mozilla.fenix.utils.Settings import kotlin.system.exitProcess import org.mozilla.fenix.GleanMetrics.Settings as SettingsMetrics @@ -394,6 +396,10 @@ class SettingsFragment : PreferenceFragmentCompat() { SettingsFragmentDirections.actionSettingsFragmentToPrivateBrowsingFragment() } + resources.getString(R.string.pref_key_tor_security_level) -> { + SettingsFragmentDirections.actionSettingsFragmentToTorSecurityLevelFragment() + } + resources.getString(R.string.pref_key_https_only_settings) -> { SettingsFragmentDirections.actionSettingsFragmentToHttpsOnlyFragment() } @@ -611,6 +617,7 @@ class SettingsFragment : PreferenceFragmentCompat() { FeatureFlags.customExtensionCollectionFeature, ) setupGeckoLogsPreference(settings) + setupSecurityLevelPreference() setupHttpsOnlyPreferences(settings) setupNotificationPreference( NotificationManagerCompat.from(requireContext()).areNotificationsEnabled(), @@ -821,6 +828,19 @@ class SettingsFragment : PreferenceFragmentCompat() { } } + @VisibleForTesting + internal fun setupSecurityLevelPreference() { + val securityLevelPreference = + requirePreference<Preference>(R.string.pref_key_tor_security_level) + securityLevelPreference.summary = + when (requireContext().settings().torSecurityLevel) { + TorSecurityLevel.STANDARD.level -> getString(R.string.tor_security_level_standard) + TorSecurityLevel.SAFER.level -> getString(R.string.tor_security_level_safer) + TorSecurityLevel.SAFEST.level -> getString(R.string.tor_security_level_safest) + else -> throw Exception("Unexpected TorSecurityLevel of ${requireContext().settings().torSecurityLevel}") + } + } + private fun updateProfilerUI(profilerStatus: Boolean) { if (profilerStatus) { findPreference<Preference>(getPreferenceKey(R.string.pref_key_start_profiler))?.title = diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevel.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevel.kt @@ -0,0 +1,13 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.tor + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +enum class TorSecurityLevel(val level: Int) : Parcelable { + STANDARD(4), SAFER(2), SAFEST(1) +} diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevelFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorSecurityLevelFragment.kt @@ -0,0 +1,146 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.tor + +import android.content.Context +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.appcompat.content.res.AppCompatResources +import androidx.fragment.app.Fragment +import mozilla.components.ui.colors.R as colorsR +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.databinding.FragmentTorSecurityLevelPreferencesBinding +import androidx.core.content.edit + +class TorSecurityLevelFragment : Fragment() { + private var _binding: FragmentTorSecurityLevelPreferencesBinding? = null + private val binding get() = _binding!! + + private val tag = "TorSecurityLevelFrag" + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + _binding = FragmentTorSecurityLevelPreferencesBinding.inflate( + inflater, container, false, + ) + + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.description.text = getString(R.string.tor_security_level_warning, getString(R.string.app_name)) + + updateSaveAndRestartButtonUI() + + val currentLevel: Int = requireContext().components.core.engine.settings.torSecurityLevel + + when (currentLevel) { + TorSecurityLevel.STANDARD.level -> { + binding.standardPreference.text = + getString(R.string.tor_security_level_standard_current_level) + binding.securityLevelRadioGroup.check(binding.standardPreference.id) + } + + TorSecurityLevel.SAFER.level -> { + binding.saferPreference.text = + getString(R.string.tor_security_level_safer_current_level) + binding.securityLevelRadioGroup.check(binding.saferPreference.id) + } + + TorSecurityLevel.SAFEST.level -> { + binding.safestPreference.text = + getString(R.string.tor_security_level_safest_current_level) + binding.securityLevelRadioGroup.check(binding.safestPreference.id) + } + } + + binding.securityLevelRadioGroup.setOnCheckedChangeListener { _, checkedId -> + binding.saveAndRestartButton.isEnabled = when (checkedId) { + binding.standardPreference.id -> currentLevel != TorSecurityLevel.STANDARD.level + binding.saferPreference.id -> currentLevel != TorSecurityLevel.SAFER.level + binding.safestPreference.id -> currentLevel != TorSecurityLevel.SAFEST.level + else -> throw Exception("unexpected checkedID of $checkedId") + } + + updateSaveAndRestartButtonUI() + } + + binding.saveAndRestartButton.setOnClickListener { + + Toast.makeText( + requireContext(), + R.string.tor_security_level_restarting, + Toast.LENGTH_SHORT, + ).show() + + val selectedSecurityLevel: Int = + when (binding.securityLevelRadioGroup.checkedRadioButtonId) { + binding.standardPreference.id -> TorSecurityLevel.STANDARD.level + binding.saferPreference.id -> TorSecurityLevel.SAFER.level + binding.safestPreference.id -> TorSecurityLevel.SAFEST.level + else -> throw Exception("Unexpected checkedRadioButtonId of ${binding.securityLevelRadioGroup.checkedRadioButtonId}") + } + + requireContext().components.core.geckoRuntime.settings.torSecurityLevel = selectedSecurityLevel + + requireActivity().getSharedPreferences("fenix_preferences", Context.MODE_PRIVATE).edit( + commit = true, + ) { + putInt( + requireContext().getString(R.string.pref_key_tor_security_level), + selectedSecurityLevel, + ) + } + + Thread.sleep(1000) + + (requireActivity() as HomeActivity).restartApplication() + } + + binding.cancelButton.setOnClickListener { + @Suppress("DEPRECATION") + requireActivity().onBackPressed() + } + } + + private fun updateSaveAndRestartButtonUI() { + binding.saveAndRestartButton.apply { + if (binding.saveAndRestartButton.isEnabled) { + backgroundTintList = AppCompatResources.getColorStateList( + requireContext(), + R.color.connect_button_purple, + ) + setTextColor( + AppCompatResources.getColorStateList( + requireContext(), + colorsR.color.photonLightGrey05, + ), + ) + } else { + backgroundTintList = AppCompatResources.getColorStateList( + requireContext(), + R.color.disabled_connect_button_purple, + ) + setTextColor( + AppCompatResources.getColorStateList( + requireContext(), + R.color.disabled_text_gray_purple, + ), + ) + } + } + } +} diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -74,6 +74,8 @@ import org.mozilla.fenix.tabstray.DefaultTabManagementFeatureHelper import org.mozilla.fenix.termsofuse.TOU_VERSION import org.mozilla.fenix.termsofuse.getApplicationInstalledTime import org.mozilla.fenix.wallpapers.Wallpaper +import org.mozilla.fenix.settings.SettingsFragment +import org.mozilla.fenix.tor.TorSecurityLevel import java.security.InvalidParameterException import java.util.UUID import java.util.concurrent.TimeUnit.MILLISECONDS @@ -525,6 +527,57 @@ class Settings( default = { FxNimbus.features.menuRedesign.value().menuBanner }, ) + private var oldStandardSecurityLevel by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_tor_security_level_standard_option), + default = false + ) + + private var oldSaferSecurityLevel by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_tor_security_level_safer_option), + default = false + ) + + private var oldSafestSecurityLevel by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_tor_security_level_safest_option), + default = false + ) + + /** + * Backing property that should used only for the [SettingsFragment] UI + * + * 4 -> STANDARD + * + * 2 -> SAFER + * + * 1 -> SAFEST + */ + var torSecurityLevel by intPreference( + appContext.getPreferenceKey(R.string.pref_key_tor_security_level), + migrateTorSecurityLevel() ?: 4, + ) + + /** + * Remove in 15.0 release. + */ + private fun migrateTorSecurityLevel(): Int? { + return when { + oldSafestSecurityLevel -> { + TorSecurityLevel.SAFEST.level + } + oldSaferSecurityLevel -> { + TorSecurityLevel.SAFER.level + } + oldStandardSecurityLevel -> { + TorSecurityLevel.STANDARD.level + } + else -> null + }.also { + oldSafestSecurityLevel = false + oldSaferSecurityLevel = false + oldStandardSecurityLevel = false + } + } + var spoofEnglish by booleanPreference( appContext.getPreferenceKey(R.string.pref_key_spoof_english), default = false, diff --git a/mobile/android/fenix/app/src/main/res/layout/fragment_tor_security_level_preferences.xml b/mobile/android/fenix/app/src/main/res/layout/fragment_tor_security_level_preferences.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:id="@+id/description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:lineSpacingExtra="6dp" + android:paddingHorizontal="24dp" + android:paddingVertical="16dp" + android:text="@string/tor_security_level_warning" + android:textColor="@color/photonLightGrey40" + android:textSize="14sp" + app:layout_constraintTop_toTopOf="parent" /> + + <RadioGroup + android:id="@+id/security_level_radio_group" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="16dp" + app:layout_constraintTop_toBottomOf="@+id/description"> + + <RadioButton + android:id="@+id/standard_preference" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/tor_security_level_standard" + android:textColor="@color/photonLightGrey05" + android:textSize="16sp" /> + + <TextView + android:id="@+id/standard_preference_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="32dp" + android:text="@string/tor_security_level_standard_description" + android:textColor="@color/photonLightGrey40" /> + + <RadioButton + android:id="@+id/safer_preference" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/tor_security_level_safer" + android:textColor="@color/photonLightGrey05" + android:textSize="16sp" /> + + <TextView + android:id="@+id/safer_preference_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="32dp" + android:text="@string/tor_security_level_safer_description" + android:textColor="@color/photonLightGrey40" /> + + <RadioButton + android:id="@+id/safest_preference" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/tor_security_level_safest" + android:textColor="@color/photonLightGrey05" + android:textSize="16sp" /> + + <TextView + android:id="@+id/safest_preference_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="32dp" + android:text="@string/tor_security_level_safest_description" + android:textColor="@color/photonLightGrey40" /> + </RadioGroup> + + <Button + android:id="@+id/save_and_restart_button" + 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:enabled="false" + android:minWidth="360dp" + android:text="@string/tor_security_level_save_and_restart_tor_browser" + android:textAlignment="center" + android:textAllCaps="false" + android:textColor="@color/photonLightGrey05" + android:textSize="14sp" + android:textStyle="bold" + app:layout_constraintBottom_toTopOf="@id/cancel_button" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + + <Button + android:id="@+id/cancel_button" + 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/configure_connection_button_white" + android:minWidth="360dp" + android:text="@string/btn_cancel" + android:textAlignment="center" + android:textAllCaps="false" + android:textColor="@color/photonDarkGrey90" + android:textSize="14sp" + android:textStyle="bold" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml b/mobile/android/fenix/app/src/main/res/navigation/nav_graph.xml @@ -102,6 +102,9 @@ android:id="@+id/action_global_homeSettingsFragment" app:destination="@id/homeSettingsFragment" /> <action + android:id="@+id/action_global_torSecurityLevelFragment" + app:destination="@id/torSecurityLevelFragment" /> + <action android:id="@+id/action_global_privateBrowsingFragment" app:destination="@id/privateBrowsingFragment" /> <action @@ -682,6 +685,13 @@ app:popEnterAnim="@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" /> <action + android:id="@+id/action_settingsFragment_to_torSecurityLevelFragment" + app:destination="@id/torSecurityLevelFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> + <action android:id="@+id/action_settingsFragment_to_privateBrowsingFragment" app:destination="@id/privateBrowsingFragment" app:enterAnim="@anim/slide_in_right" @@ -1007,6 +1017,10 @@ app:popExitAnim="@anim/slide_out_right" /> </fragment> <fragment + android:id="@+id/torSecurityLevelFragment" + android:name="org.mozilla.fenix.tor.TorSecurityLevelFragment" + android:label="@string/preferences_tor_security_level_options" /> + <fragment android:id="@+id/privateBrowsingFragment" android:name="org.mozilla.fenix.settings.PrivateBrowsingFragment" android:label="@string/preferences_private_browsing_options" > diff --git a/mobile/android/fenix/app/src/main/res/values/preference_keys.xml b/mobile/android/fenix/app/src/main/res/values/preference_keys.xml @@ -531,5 +531,14 @@ <string name="pref_key_extensions_version" translatable="false">pref_key_extensions_version</string> <string name="pref_key_https_everywhere_removed" translatable="false">pref_key_https_everywhere_removed</string> + <!-- Security Level Settings --> + <string name="pref_key_tor_security_level" translatable="false">pref_key_tor_security_level</string> + + <!-- Deprecated Security Level Settings --> + <string name="pref_key_tor_security_level_settings" translatable="false">pref_key_tor_security_level_settings</string> + <string name="pref_key_tor_security_level_standard_option" translatable="false">pref_key_tor_security_level_standard_option</string> + <string name="pref_key_tor_security_level_safer_option" translatable="false">pref_key_tor_security_level_safer_option</string> + <string name="pref_key_tor_security_level_safest_option" translatable="false">pref_key_tor_security_level_safest_option</string> + <string name="pref_key_spoof_english" translatable="false">pref_key_spoof_english</string> </resources> diff --git a/mobile/android/fenix/app/src/main/res/xml/preferences.xml b/mobile/android/fenix/app/src/main/res/xml/preferences.xml @@ -97,6 +97,11 @@ android:layout="@layout/preference_category_no_icon_style"> <androidx.preference.Preference + android:key="@string/pref_key_tor_security_level" + app:iconSpaceReserved="false" + android:title="@string/preferences_tor_security_level_options" /> + + <androidx.preference.Preference android:key="@string/pref_key_private_browsing" app:iconSpaceReserved="false" app:isPreferenceVisible="false" diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorAndroidIntegration.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorAndroidIntegration.java @@ -48,6 +48,9 @@ public class TorAndroidIntegration implements BundleEventListener { private static final String EVENT_SETTINGS_CHANGED = "GeckoView:Tor:SettingsChanged"; // Events we emit + // TODO: Integrate the security level API. tor-browser#43820 + private static final String EVENT_SECURITY_LEVEL_GET = "GeckoView:Tor:SecurityLevelGet"; + private static final String EVENT_SECURITY_LEVEL_SET_BEFORE_RESTART = "GeckoView:Tor:SecurityLevelSetBeforeRestart"; private static final String EVENT_SETTINGS_GET = "GeckoView:Tor:SettingsGet"; private static final String EVENT_SETTINGS_SET = "GeckoView:Tor:SettingsSet"; private static final String EVENT_BOOTSTRAP_BEGIN = "GeckoView:Tor:BootstrapBegin"; diff --git a/toolkit/modules/TorAndroidIntegration.sys.mjs b/toolkit/modules/TorAndroidIntegration.sys.mjs @@ -11,6 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, { TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs", TorProviderTopics: "resource://gre/modules/TorProviderBuilder.sys.mjs", TorSettings: "resource://gre/modules/TorSettings.sys.mjs", + SecurityLevelPrefs: "resources://gre/modules/SecurityLevel.sys.mjs", }); const Prefs = Object.freeze({ @@ -33,6 +34,8 @@ const EmittedEvents = Object.freeze({ }); const ListenedEvents = Object.freeze({ + securityLevelGet: "GeckoView:Tor:SecurityLevelGet", + securityLevelSetBeforeRestart: "GeckoView:Tor:SecurityLevelSetBeforeRestart", settingsGet: "GeckoView:Tor:SettingsGet", // The data is passed directly to TorSettings. settingsSet: "GeckoView:Tor:SettingsSet", @@ -164,6 +167,20 @@ class TorAndroidIntegrationImpl { logger.debug(`Received event ${event}`, data); try { switch (event) { + case ListenedEvents.securityLevelGet: + // "standard"/"safer"/"safest" + // TODO: Switch to securityLevelSummary to allow android to handle + // "custom" security level. tor-browser#43819 + callback?.onSuccess(lazy.SecurityLevelPrefs.securityLevel); + break; + case ListenedEvents.securityLevelSetBeforeRestart: + lazy.SecurityLevelPrefs.setSecurityLevelBeforeRestart(data.levelName); + // Let the caller know that the setting is applied and the browser + // should be restarted now. + // NOTE: The caller must wait for this callback before triggering + // the restart. + callback?.onSuccess(); + break; case ListenedEvents.settingsGet: callback?.onSuccess(lazy.TorSettings.getSettings()); return;