Commit 108bd3eb authored by Matthew Finkel's avatar Matthew Finkel
Browse files

Bug 40026: Implement Security Level settings

parent 3229789d
......@@ -8,6 +8,7 @@ import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.tor_onboarding_security_level.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.sessioncontrol.OnboardingInteractor
import org.mozilla.fenix.onboarding.OnboardingRadioButton
import org.mozilla.fenix.utils.view.addToRadioGroup
......@@ -33,19 +34,27 @@ class TorOnboardingSecurityLevelViewHolder(
)
view.open_settings_button.setOnClickListener {
interactor.onOpenSettingsClicked()
interactor.onOpenSecurityLevelSettingsClicked()
}
setupRadioGroup()
setupRadioGroup(view)
}
private fun setupRadioGroup() {
private fun setupRadioGroup(view: View) {
addToRadioGroup(standardSecurityLevel, saferSecurityLevel, safestSecurityLevel)
standardSecurityLevel.isChecked = true
safestSecurityLevel.isChecked = false
saferSecurityLevel.isChecked = false
val securityLevel = try {
SecurityLevelUtil.getSecurityLevelFromInt(
view.context.components.core.engine.settings.torSecurityLevel
)
} catch (e: IllegalStateException) {
SecurityLevel.STANDARD
}
standardSecurityLevel.isChecked = securityLevel == SecurityLevel.STANDARD
safestSecurityLevel.isChecked = securityLevel == SecurityLevel.SAFEST
saferSecurityLevel.isChecked = securityLevel == SecurityLevel.SAFER
standardSecurityLevel.onClickListener {
updateSecurityLevel()
......
/* 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.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.SecurityLevel
import org.mozilla.fenix.tor.SecurityLevelUtil
import org.mozilla.fenix.utils.view.GroupableRadioButton
import org.mozilla.fenix.utils.view.addToRadioGroup
import org.mozilla.fenix.utils.view.uncheckAll
/**
* Lets the user choose their security level
*/
@Suppress("SpreadOperator")
class TorSecurityLevelFragment : PreferenceFragmentCompat() {
private val securityLevelRadioGroups = mutableListOf<GroupableRadioButton>()
private var previousSecurityLevel: SecurityLevel? = null
override fun onResume() {
super.onResume()
showToolbar(getString(R.string.preferences_tor_security_level_options))
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.tor_security_level_preferences, rootKey)
val currentLevel: SecurityLevel? = context?.components?.let {
try {
SecurityLevelUtil.getSecurityLevelFromInt(
it.core.engine.settings.torSecurityLevel
)
} catch (e: IllegalStateException) {
// The default state is 0. If we get an invalid state then
// default to Standard (4).
SecurityLevel.STANDARD
}
}
if (currentLevel == null) {
throw IllegalStateException("context or Components is null.")
}
val radioSafer = bindSecurityLevelRadio(SecurityLevel.SAFER)
val radioSafest = bindSecurityLevelRadio(SecurityLevel.SAFEST)
val radioStandard = bindSecurityLevelRadio(SecurityLevel.STANDARD)
securityLevelRadioGroups.addAll(mutableListOf(radioSafer, radioSafest, radioStandard))
// `*` is Kotlin's "spread" operator, for expanding an Array as a vararg.
addToRadioGroup(*securityLevelRadioGroups.toTypedArray())
securityLevelRadioGroups.uncheckAll()
val securityLevelRadioButton = requirePreference<RadioButtonPreference>(currentLevel.preferenceKey)
// Cache this for later comparison in the OnPreferenceChangeListener
previousSecurityLevel = currentLevel
securityLevelRadioButton.setCheckedWithoutClickListener(true)
}
private fun bindSecurityLevelRadio(
level: SecurityLevel
): RadioButtonPreference {
val radio = requirePreference<RadioButtonPreference>(level.preferenceKey)
radio.summary = getString(level.contentDescriptionRes)
radio.apply {
setOnPreferenceChangeListener<Boolean> { preference, isChecked ->
if (isChecked && (previousSecurityLevel!! != level)) {
preference.context.components.core.engine.settings.torSecurityLevel =
level.intRepresentation
previousSecurityLevel = level
}
true
}
}
return radio
}
}
/* 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 SecurityLevel(
@StringRes val preferenceKey: Int,
@StringRes val contentDescriptionRes: Int,
val intRepresentation: Int
) : Parcelable {
STANDARD(
preferenceKey = R.string.pref_key_tor_security_level_standard_option,
contentDescriptionRes = R.string.tor_security_level_standard_description,
intRepresentation = SecurityLevel.SECURITY_LEVEL_STANDARD
),
SAFER(
preferenceKey = R.string.pref_key_tor_security_level_safer_option,
contentDescriptionRes = R.string.tor_security_level_safer_description,
intRepresentation = SecurityLevel.SECURITY_LEVEL_SAFER
),
SAFEST(
preferenceKey = R.string.pref_key_tor_security_level_safest_option,
contentDescriptionRes = R.string.tor_security_level_safest_description,
intRepresentation = SecurityLevel.SECURITY_LEVEL_SAFEST
);
companion object {
const val SECURITY_LEVEL_STANDARD = 4
const val SECURITY_LEVEL_SAFER = 2
const val SECURITY_LEVEL_SAFEST = 1
}
}
object SecurityLevelUtil {
fun getSecurityLevelFromInt(level: Int): SecurityLevel {
return when (level) {
SecurityLevel.SECURITY_LEVEL_STANDARD -> SecurityLevel.STANDARD
SecurityLevel.SECURITY_LEVEL_SAFER -> SecurityLevel.SAFER
SecurityLevel.SECURITY_LEVEL_SAFEST -> SecurityLevel.SAFEST
else -> throw IllegalStateException("Security Level $level is not valid")
}
}
}
......@@ -665,6 +665,10 @@
android:id="@+id/customizationFragment"
android:name="org.mozilla.fenix.settings.CustomizationFragment"
android:label="@string/preferences_customize" />
<fragment
android:id="@+id/torSecurityLevelFragment"
android:name="org.mozilla.fenix.settings.TorSecurityLevelFragment"
android:label="@string/preferences_tor_security_level_settings" />
<fragment
android:id="@+id/privateBrowsingFragment"
android:name="org.mozilla.fenix.settings.PrivateBrowsingFragment"
......
......@@ -234,7 +234,7 @@
<!-- 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_default" translatable="false">pref_key_tor_security_level_standard_default</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>
......
......@@ -61,4 +61,8 @@
<string name="tor_security_level_safer_description">Disable website features that are often dangerous, causing some sites to lose functionality.</string>
<string name="tor_security_level_safest_option">Safest</string>
<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>
<!-- Preference title for security level settings -->
<string name="preferences_tor_security_level_settings">Security Settings</string>
<string name="preferences_tor_security_level_options">Security Level</string>
</resources>
<?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.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.mozilla.fenix.settings.RadioButtonPreference
android:defaultValue="true"
android:key="@string/pref_key_tor_security_level_standard_option"
android:summary="@string/tor_security_level_standard_description"
android:title="@string/tor_security_level_standard_option" />
<org.mozilla.fenix.settings.RadioButtonPreference
android:defaultValue="false"
android:key="@string/pref_key_tor_security_level_safer_option"
android:summary="@string/tor_security_level_safer_description"
android:title="@string/tor_security_level_safer_option" />
<org.mozilla.fenix.settings.RadioButtonPreference
android:defaultValue="false"
android:key="@string/pref_key_tor_security_level_safest_option"
android:summary="@string/tor_security_level_safest_description"
android:title="@string/tor_security_level_safest_option" />
</androidx.preference.PreferenceScreen>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment