Loading app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +3 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,9 @@ class SettingsFragment : PreferenceFragmentCompat() { resources.getString(R.string.pref_key_search_settings) -> { SettingsFragmentDirections.actionSettingsFragmentToSearchEngineFragment() } resources.getString(R.string.pref_key_tor_network_settings) -> { SettingsFragmentDirections.actionSettingsFragmentToTorNetworkSettingsFragment() } resources.getString(R.string.pref_key_tracking_protection_settings) -> { requireContext().metrics.track(Event.TrackingProtectionSettings) SettingsFragmentDirections.actionSettingsFragmentToTrackingProtectionFragment() Loading app/src/main/java/org/mozilla/fenix/settings/TorBridgeConfigFragment.kt 0 → 100644 +162 −0 Original line number Diff line number Diff line /* 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.settings import android.os.Bundle import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference import org.mozilla.fenix.Config import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.tor.TorBridgeTransportConfig import org.mozilla.fenix.utils.view.addToRadioGroup import org.mozilla.fenix.utils.view.GroupableRadioButton import org.mozilla.fenix.utils.view.uncheckAll /** * Displays the toggle for enabling bridges, options for built-in pluggable transports, and an additional * preference for configuring a user-provided bridge. */ @Suppress("SpreadOperator") class TorBridgeConfigFragment : PreferenceFragmentCompat() { private val builtinBridgeRadioGroups = mutableListOf<GroupableRadioButton>() private var previousTransportConfig: TorBridgeTransportConfig? = null override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.tor_bridge_config_preferences, rootKey) // Initialize radio button group for built-in bridge transport types val radioObfs4 = bindBridgeTransportRadio(TorBridgeTransportConfig.BUILTIN_OBFS4) val radioMeekAzure = bindBridgeTransportRadio(TorBridgeTransportConfig.BUILTIN_MEEK_AZURE) val radioSnowflake = bindBridgeTransportRadio(TorBridgeTransportConfig.BUILTIN_SNOWFLAKE) builtinBridgeRadioGroups.addAll(mutableListOf(radioObfs4, radioMeekAzure, radioSnowflake)) // `*` is Kotlin's "spread" operator, for expanding an Array as a vararg. addToRadioGroup(*builtinBridgeRadioGroups.toTypedArray()) // Snowflake is not available on Release at this time. if (Config.channel.isRelease) { radioSnowflake.apply { isVisible = false } } } override fun onResume() { super.onResume() showToolbar(getString(R.string.preferences_tor_network_settings_bridge_config)) val bridgesEnabled = requireContext().components.torController.bridgesEnabled val prefBridgeConfig = requirePreference<SwitchPreference>(R.string.pref_key_tor_network_settings_bridge_config_toggle) prefBridgeConfig.apply { isChecked = bridgesEnabled setOnPreferenceChangeListener<Boolean> { preference, enabled -> preference.context.components.torController.bridgesEnabled = enabled updateCurrentConfiguredBridgePref(preference) preference.context.components.torController.restartTor() true } } val userProvidedBridges = requirePreference<EditTextPreference>( R.string.pref_key_tor_network_settings_bridge_config_user_provided_bridge ) userProvidedBridges.apply { setOnPreferenceChangeListener<String> { preference, userProvidedBridge -> builtinBridgeRadioGroups.uncheckAll() preference.context.components.torController.bridgeTransport = TorBridgeTransportConfig.USER_PROVIDED preference.context.components.torController.userProvidedBridges = userProvidedBridge updateCurrentConfiguredBridgePref(preference) preference.context.components.torController.restartTor() true } val userProvidedBridge: String? = context.components.torController.userProvidedBridges if (userProvidedBridge != null) { setText(userProvidedBridge) } } val currentBridgeType = prefBridgeConfig.context.components.torController.bridgeTransport // Cache the current configured transport type previousTransportConfig = currentBridgeType builtinBridgeRadioGroups.uncheckAll() if (currentBridgeType != TorBridgeTransportConfig.USER_PROVIDED) { val bridgeRadioButton = requirePreference<RadioButtonPreference>(currentBridgeType.preferenceKey) bridgeRadioButton.setCheckedWithoutClickListener(true) } updateCurrentConfiguredBridgePref(prefBridgeConfig) } private fun bindBridgeTransportRadio( bridge: TorBridgeTransportConfig ): RadioButtonPreference { val radio = requirePreference<RadioButtonPreference>(bridge.preferenceKey) radio.apply { setOnPreferenceChangeListener<Boolean> { preference, isChecked -> if (isChecked && (previousTransportConfig!! != bridge)) { preference.context.components.torController.bridgeTransport = bridge previousTransportConfig = bridge updateCurrentConfiguredBridgePref(preference) context.components.torController.restartTor() } true } } return radio } private fun setCurrentBridgeLabel(currentBridgePref: Preference?, bridge: String) { currentBridgePref?.apply { title = getString( R .string .preferences_tor_network_settings_bridge_config_current_bridge, bridge ) } } private fun updateCurrentConfiguredBridgePref(preference: Preference) { val currentBridge: Preference? = findPreference( getString( R.string.pref_key_tor_network_settings_bridge_config_current_bridge ) ) val enabled = requireContext().components.torController.bridgesEnabled if (enabled) { val configuredBridge = preference.context.components.torController.bridgeTransport var bridges = when (configuredBridge) { TorBridgeTransportConfig.USER_PROVIDED -> preference.context.components.torController.userProvidedBridges else -> configuredBridge.transportName } if (bridges == null) { bridges = "not known" } setCurrentBridgeLabel(currentBridge, bridges) } else { setCurrentBridgeLabel( currentBridge, getString(R.string.tor_network_settings_bridge_not_configured) ) } } } app/src/main/java/org/mozilla/fenix/settings/TorNetworkSettingsFragment.kt 0 → 100644 +162 −0 Original line number Diff line number Diff line /* 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.settings import android.os.Bundle import androidx.navigation.findNavController import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.tor.TorBridgeTransportConfig import org.mozilla.fenix.tor.TorEvents /** * Lets the user configure Tor network connection settings */ class TorNetworkSettingsFragment : PreferenceFragmentCompat(), TorEvents { override fun onResume() { super.onResume() val torController = requireContext().components.torController torController.registerTorListener(this) showToolbar(getString(R.string.preferences_tor_network_settings)) val yesString = getString(R.string.preferences_tor_network_settings_yes) val noString = getString(R.string.preferences_tor_network_settings_no) requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridge_config).apply { setOnPreferenceClickListener { val directions = TorNetworkSettingsFragmentDirections .actionTorNetworkSettingsFragmentToTorBridgeConfigFragment() requireView().findNavController().navigate(directions) true } if (torController.bridgesEnabled) { if (torController.bridgeTransport == TorBridgeTransportConfig.USER_PROVIDED) { summary = getString( R .string .preferences_tor_network_settings_bridge_config_description_user_provided_enabled ) } else { summary = getString( R .string .preferences_tor_network_settings_bridge_config_description_builtin_transport_enabled ) } } else { summary = getString( R .string .preferences_tor_network_settings_bridge_config_description ) } } requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridges_enabled).apply { val formatStringRes = R.string.preferences_tor_network_settings_bridges_enabled title = if (torController.bridgesEnabled) { getString(formatStringRes, yesString) } else { getString(formatStringRes, noString) } } setStatus() } private fun setStatus() { val torController = requireContext().components.torController val yesString = getString(R.string.preferences_tor_network_settings_yes) val noString = getString(R.string.preferences_tor_network_settings_no) requirePreference<Preference>(R.string.pref_key_tor_network_settings_tor_ready).apply { val formatStringRes = R.string.preferences_tor_network_settings_tor_ready @SuppressWarnings("ComplexCondition") title = if (!torController.isStarting && torController.isConnected && torController.isBootstrapped && !torController.isRestarting) { getString(formatStringRes, yesString) } else { getString(formatStringRes, noString) } } requirePreference<Preference>(R.string.pref_key_tor_network_settings_state).apply { val formatStringRes = R.string.preferences_tor_network_settings_state title = if (torController.isRestarting) { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_restarting ) ) } else if (torController.isStarting) { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_connecting ) ) } else if (torController.isConnected) { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_connected ) ) } else { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_disconnected ) ) } } } override fun onStop() { super.onStop() requireContext().components.torController.unregisterTorListener(this) } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.tor_network_settings_preferences, rootKey) } @SuppressWarnings("EmptyFunctionBlock") override fun onTorConnecting() { } @SuppressWarnings("EmptyFunctionBlock") override fun onTorConnected() { } @SuppressWarnings("EmptyFunctionBlock") override fun onTorStopped() { } override fun onTorStatusUpdate(entry: String?, status: String?) { setStatus() } } app/src/main/java/org/mozilla/fenix/tor/TorBridgeTransports.kt 0 → 100644 +48 −0 Original line number Diff line number Diff line /* 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 androidx.annotation.StringRes import kotlinx.android.parcel.Parcelize import org.mozilla.fenix.R @Parcelize enum class TorBridgeTransportConfig( @StringRes val preferenceKey: Int, val transportName: String ) : Parcelable { BUILTIN_OBFS4( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_builtin_bridge_obfs4, transportName = "obfs4" ), BUILTIN_MEEK_AZURE( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_builtin_bridge_meek_azure, transportName = "meek" ), BUILTIN_SNOWFLAKE( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_builtin_bridge_snowflake, transportName = "snowflake" ), USER_PROVIDED( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_user_provided_bridge, transportName = "user_provided" ) } object TorBridgeTransportConfigUtil { fun getStringToBridgeTransport(bridge: String): TorBridgeTransportConfig { return when (bridge) { TorBridgeTransportConfig.BUILTIN_OBFS4.transportName -> TorBridgeTransportConfig.BUILTIN_OBFS4 TorBridgeTransportConfig.BUILTIN_MEEK_AZURE.transportName -> TorBridgeTransportConfig.BUILTIN_MEEK_AZURE TorBridgeTransportConfig.BUILTIN_SNOWFLAKE.transportName -> TorBridgeTransportConfig.BUILTIN_SNOWFLAKE else -> TorBridgeTransportConfig.USER_PROVIDED } } } app/src/main/res/drawable/ic_tor_config_bridge.xml 0 → 100644 +9 −0 Original line number Diff line number Diff line <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="18dp" android:height="18dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M22.7,19l-9.1,-9.1c0.9,-2.3 0.4,-5 -1.5,-6.9 -2,-2 -5,-2.4 -7.4,-1.3L9,6 6,9 1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1,0.4 1.4,0l2.3,-2.3c0.5,-0.4 0.5,-1.1 0.1,-1.4z" android:fillColor="#ffffff"/> </vector> Loading
app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +3 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,9 @@ class SettingsFragment : PreferenceFragmentCompat() { resources.getString(R.string.pref_key_search_settings) -> { SettingsFragmentDirections.actionSettingsFragmentToSearchEngineFragment() } resources.getString(R.string.pref_key_tor_network_settings) -> { SettingsFragmentDirections.actionSettingsFragmentToTorNetworkSettingsFragment() } resources.getString(R.string.pref_key_tracking_protection_settings) -> { requireContext().metrics.track(Event.TrackingProtectionSettings) SettingsFragmentDirections.actionSettingsFragmentToTrackingProtectionFragment() Loading
app/src/main/java/org/mozilla/fenix/settings/TorBridgeConfigFragment.kt 0 → 100644 +162 −0 Original line number Diff line number Diff line /* 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.settings import android.os.Bundle import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference import org.mozilla.fenix.Config import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.tor.TorBridgeTransportConfig import org.mozilla.fenix.utils.view.addToRadioGroup import org.mozilla.fenix.utils.view.GroupableRadioButton import org.mozilla.fenix.utils.view.uncheckAll /** * Displays the toggle for enabling bridges, options for built-in pluggable transports, and an additional * preference for configuring a user-provided bridge. */ @Suppress("SpreadOperator") class TorBridgeConfigFragment : PreferenceFragmentCompat() { private val builtinBridgeRadioGroups = mutableListOf<GroupableRadioButton>() private var previousTransportConfig: TorBridgeTransportConfig? = null override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.tor_bridge_config_preferences, rootKey) // Initialize radio button group for built-in bridge transport types val radioObfs4 = bindBridgeTransportRadio(TorBridgeTransportConfig.BUILTIN_OBFS4) val radioMeekAzure = bindBridgeTransportRadio(TorBridgeTransportConfig.BUILTIN_MEEK_AZURE) val radioSnowflake = bindBridgeTransportRadio(TorBridgeTransportConfig.BUILTIN_SNOWFLAKE) builtinBridgeRadioGroups.addAll(mutableListOf(radioObfs4, radioMeekAzure, radioSnowflake)) // `*` is Kotlin's "spread" operator, for expanding an Array as a vararg. addToRadioGroup(*builtinBridgeRadioGroups.toTypedArray()) // Snowflake is not available on Release at this time. if (Config.channel.isRelease) { radioSnowflake.apply { isVisible = false } } } override fun onResume() { super.onResume() showToolbar(getString(R.string.preferences_tor_network_settings_bridge_config)) val bridgesEnabled = requireContext().components.torController.bridgesEnabled val prefBridgeConfig = requirePreference<SwitchPreference>(R.string.pref_key_tor_network_settings_bridge_config_toggle) prefBridgeConfig.apply { isChecked = bridgesEnabled setOnPreferenceChangeListener<Boolean> { preference, enabled -> preference.context.components.torController.bridgesEnabled = enabled updateCurrentConfiguredBridgePref(preference) preference.context.components.torController.restartTor() true } } val userProvidedBridges = requirePreference<EditTextPreference>( R.string.pref_key_tor_network_settings_bridge_config_user_provided_bridge ) userProvidedBridges.apply { setOnPreferenceChangeListener<String> { preference, userProvidedBridge -> builtinBridgeRadioGroups.uncheckAll() preference.context.components.torController.bridgeTransport = TorBridgeTransportConfig.USER_PROVIDED preference.context.components.torController.userProvidedBridges = userProvidedBridge updateCurrentConfiguredBridgePref(preference) preference.context.components.torController.restartTor() true } val userProvidedBridge: String? = context.components.torController.userProvidedBridges if (userProvidedBridge != null) { setText(userProvidedBridge) } } val currentBridgeType = prefBridgeConfig.context.components.torController.bridgeTransport // Cache the current configured transport type previousTransportConfig = currentBridgeType builtinBridgeRadioGroups.uncheckAll() if (currentBridgeType != TorBridgeTransportConfig.USER_PROVIDED) { val bridgeRadioButton = requirePreference<RadioButtonPreference>(currentBridgeType.preferenceKey) bridgeRadioButton.setCheckedWithoutClickListener(true) } updateCurrentConfiguredBridgePref(prefBridgeConfig) } private fun bindBridgeTransportRadio( bridge: TorBridgeTransportConfig ): RadioButtonPreference { val radio = requirePreference<RadioButtonPreference>(bridge.preferenceKey) radio.apply { setOnPreferenceChangeListener<Boolean> { preference, isChecked -> if (isChecked && (previousTransportConfig!! != bridge)) { preference.context.components.torController.bridgeTransport = bridge previousTransportConfig = bridge updateCurrentConfiguredBridgePref(preference) context.components.torController.restartTor() } true } } return radio } private fun setCurrentBridgeLabel(currentBridgePref: Preference?, bridge: String) { currentBridgePref?.apply { title = getString( R .string .preferences_tor_network_settings_bridge_config_current_bridge, bridge ) } } private fun updateCurrentConfiguredBridgePref(preference: Preference) { val currentBridge: Preference? = findPreference( getString( R.string.pref_key_tor_network_settings_bridge_config_current_bridge ) ) val enabled = requireContext().components.torController.bridgesEnabled if (enabled) { val configuredBridge = preference.context.components.torController.bridgeTransport var bridges = when (configuredBridge) { TorBridgeTransportConfig.USER_PROVIDED -> preference.context.components.torController.userProvidedBridges else -> configuredBridge.transportName } if (bridges == null) { bridges = "not known" } setCurrentBridgeLabel(currentBridge, bridges) } else { setCurrentBridgeLabel( currentBridge, getString(R.string.tor_network_settings_bridge_not_configured) ) } } }
app/src/main/java/org/mozilla/fenix/settings/TorNetworkSettingsFragment.kt 0 → 100644 +162 −0 Original line number Diff line number Diff line /* 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.settings import android.os.Bundle import androidx.navigation.findNavController import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.tor.TorBridgeTransportConfig import org.mozilla.fenix.tor.TorEvents /** * Lets the user configure Tor network connection settings */ class TorNetworkSettingsFragment : PreferenceFragmentCompat(), TorEvents { override fun onResume() { super.onResume() val torController = requireContext().components.torController torController.registerTorListener(this) showToolbar(getString(R.string.preferences_tor_network_settings)) val yesString = getString(R.string.preferences_tor_network_settings_yes) val noString = getString(R.string.preferences_tor_network_settings_no) requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridge_config).apply { setOnPreferenceClickListener { val directions = TorNetworkSettingsFragmentDirections .actionTorNetworkSettingsFragmentToTorBridgeConfigFragment() requireView().findNavController().navigate(directions) true } if (torController.bridgesEnabled) { if (torController.bridgeTransport == TorBridgeTransportConfig.USER_PROVIDED) { summary = getString( R .string .preferences_tor_network_settings_bridge_config_description_user_provided_enabled ) } else { summary = getString( R .string .preferences_tor_network_settings_bridge_config_description_builtin_transport_enabled ) } } else { summary = getString( R .string .preferences_tor_network_settings_bridge_config_description ) } } requirePreference<Preference>(R.string.pref_key_tor_network_settings_bridges_enabled).apply { val formatStringRes = R.string.preferences_tor_network_settings_bridges_enabled title = if (torController.bridgesEnabled) { getString(formatStringRes, yesString) } else { getString(formatStringRes, noString) } } setStatus() } private fun setStatus() { val torController = requireContext().components.torController val yesString = getString(R.string.preferences_tor_network_settings_yes) val noString = getString(R.string.preferences_tor_network_settings_no) requirePreference<Preference>(R.string.pref_key_tor_network_settings_tor_ready).apply { val formatStringRes = R.string.preferences_tor_network_settings_tor_ready @SuppressWarnings("ComplexCondition") title = if (!torController.isStarting && torController.isConnected && torController.isBootstrapped && !torController.isRestarting) { getString(formatStringRes, yesString) } else { getString(formatStringRes, noString) } } requirePreference<Preference>(R.string.pref_key_tor_network_settings_state).apply { val formatStringRes = R.string.preferences_tor_network_settings_state title = if (torController.isRestarting) { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_restarting ) ) } else if (torController.isStarting) { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_connecting ) ) } else if (torController.isConnected) { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_connected ) ) } else { getString(formatStringRes, getString( R .string .preferences_tor_network_settings_disconnected ) ) } } } override fun onStop() { super.onStop() requireContext().components.torController.unregisterTorListener(this) } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.tor_network_settings_preferences, rootKey) } @SuppressWarnings("EmptyFunctionBlock") override fun onTorConnecting() { } @SuppressWarnings("EmptyFunctionBlock") override fun onTorConnected() { } @SuppressWarnings("EmptyFunctionBlock") override fun onTorStopped() { } override fun onTorStatusUpdate(entry: String?, status: String?) { setStatus() } }
app/src/main/java/org/mozilla/fenix/tor/TorBridgeTransports.kt 0 → 100644 +48 −0 Original line number Diff line number Diff line /* 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 androidx.annotation.StringRes import kotlinx.android.parcel.Parcelize import org.mozilla.fenix.R @Parcelize enum class TorBridgeTransportConfig( @StringRes val preferenceKey: Int, val transportName: String ) : Parcelable { BUILTIN_OBFS4( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_builtin_bridge_obfs4, transportName = "obfs4" ), BUILTIN_MEEK_AZURE( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_builtin_bridge_meek_azure, transportName = "meek" ), BUILTIN_SNOWFLAKE( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_builtin_bridge_snowflake, transportName = "snowflake" ), USER_PROVIDED( preferenceKey = R.string.pref_key_tor_network_settings_bridge_config_user_provided_bridge, transportName = "user_provided" ) } object TorBridgeTransportConfigUtil { fun getStringToBridgeTransport(bridge: String): TorBridgeTransportConfig { return when (bridge) { TorBridgeTransportConfig.BUILTIN_OBFS4.transportName -> TorBridgeTransportConfig.BUILTIN_OBFS4 TorBridgeTransportConfig.BUILTIN_MEEK_AZURE.transportName -> TorBridgeTransportConfig.BUILTIN_MEEK_AZURE TorBridgeTransportConfig.BUILTIN_SNOWFLAKE.transportName -> TorBridgeTransportConfig.BUILTIN_SNOWFLAKE else -> TorBridgeTransportConfig.USER_PROVIDED } } }
app/src/main/res/drawable/ic_tor_config_bridge.xml 0 → 100644 +9 −0 Original line number Diff line number Diff line <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="18dp" android:height="18dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M22.7,19l-9.1,-9.1c0.9,-2.3 0.4,-5 -1.5,-6.9 -2,-2 -5,-2.4 -7.4,-1.3L9,6 6,9 1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1,0.4 1.4,0l2.3,-2.3c0.5,-0.4 0.5,-1.1 0.1,-1.4z" android:fillColor="#ffffff"/> </vector>