[tor-commits] [Git][tpo/applications/fenix][tor-browser-81.1.1-10.0-1] 5 commits: fixup! Bug 40028: Implement Tor Onboarding

Matthew Finkel gitlab at torproject.org
Thu Oct 1 15:48:03 UTC 2020



Matthew Finkel pushed to branch tor-browser-81.1.1-10.0-1 at The Tor Project / Applications / fenix


Commits:
dbb92015 by Matthew Finkel at 2020-09-30T18:34:52+00:00
fixup! Bug 40028: Implement Tor Onboarding

- - - - -
dcb56537 by Matthew Finkel at 2020-09-30T21:15:09+00:00
Bug 40026: Implement Security Level settings

- - - - -
0f1c4980 by Matthew Finkel at 2020-09-30T21:15:09+00:00
Bug 40026: Integrate Security Level settings

- - - - -
d54480c4 by Matthew Finkel at 2020-10-01T15:45:22+00:00
fixup! Bug 34378: Port external helper app prompting

- - - - -
d7f419b3 by Matthew Finkel at 2020-10-01T15:47:50+00:00
Merge branch 'bug_40026_06' into tor-browser-81.1.1-10.0-1

- - - - -


12 changed files:

- app/src/main/java/org/mozilla/fenix/HomeActivity.kt
- app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
- app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt
- app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
- + app/src/main/java/org/mozilla/fenix/settings/TorSecurityLevelFragment.kt
- + app/src/main/java/org/mozilla/fenix/tor/SecurityLevel.kt
- app/src/main/res/layout/tor_onboarding_security_level.xml
- app/src/main/res/navigation/nav_graph.xml
- app/src/main/res/values/preference_keys.xml
- app/src/main/res/values/torbrowser_strings.xml
- app/src/main/res/xml/preferences.xml
- + app/src/main/res/xml/tor_security_level_preferences.xml


Changes:

=====================================
app/src/main/java/org/mozilla/fenix/HomeActivity.kt
=====================================
@@ -416,6 +416,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
             if (startIntent.creatorPackage == applicationContext.packageName) {
                 val dialog = getOrCreateDialog()
                 dialog.onConfirmRedirect = {
+                    @Suppress("EmptyCatchBlock")
                     try {
                         startIntent.send()
                     } catch (error: PendingIntent.CanceledException) {


=====================================
app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
=====================================
@@ -367,6 +367,8 @@ class DefaultSessionControlController(
     }
 
     override fun handleOpenSecurityLevelSettingsClicked() {
+        val directions = HomeFragmentDirections.actionGlobalTorSecurityLevelFragment()
+        navController.nav(R.id.homeFragment, directions)
     }
 
     override fun handleWhatsNewGetAnswersClicked() {


=====================================
app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt
=====================================
@@ -8,8 +8,11 @@ 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.tor.SecurityLevel
+import org.mozilla.fenix.tor.SecurityLevelUtil
 import org.mozilla.fenix.utils.view.addToRadioGroup
 
 class TorOnboardingSecurityLevelViewHolder(
@@ -24,7 +27,7 @@ class TorOnboardingSecurityLevelViewHolder(
     init {
         view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_tracking_protection)
 
-        standardSecurityLevel = view.security_level_standard_default
+        standardSecurityLevel = view.security_level_standard_option
         saferSecurityLevel = view.security_level_safer_option
         safestSecurityLevel = view.security_level_safest_option
 
@@ -33,34 +36,45 @@ 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()
+            updateSecurityLevel(SecurityLevel.STANDARD)
         }
 
         saferSecurityLevel.onClickListener {
-            updateSecurityLevel()
+            updateSecurityLevel(SecurityLevel.SAFER)
         }
 
         safestSecurityLevel.onClickListener {
-            updateSecurityLevel()
+            updateSecurityLevel(SecurityLevel.SAFEST)
         }
     }
 
-    private fun updateSecurityLevel() {
+    private fun updateSecurityLevel(newLevel: SecurityLevel) {
+        itemView.context.components.let {
+            it.core.engine.settings.torSecurityLevel = newLevel.intRepresentation
+        }
     }
 
     companion object {


=====================================
app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
=====================================
@@ -217,6 +217,9 @@ class SettingsFragment : PreferenceFragmentCompat() {
             resources.getString(R.string.pref_key_tor_network_settings) -> {
                 SettingsFragmentDirections.actionSettingsFragmentToTorNetworkSettingsFragment()
             }
+            resources.getString(R.string.pref_key_tor_security_level_settings) -> {
+                SettingsFragmentDirections.actionSettingsFragmentToTorSecurityLevelFragment()
+            }
             resources.getString(R.string.pref_key_tracking_protection_settings) -> {
                 requireContext().metrics.track(Event.TrackingProtectionSettings)
                 SettingsFragmentDirections.actionSettingsFragmentToTrackingProtectionFragment()


=====================================
app/src/main/java/org/mozilla/fenix/settings/TorSecurityLevelFragment.kt
=====================================
@@ -0,0 +1,86 @@
+/* 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
+ */
+ at 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
+    }
+}


=====================================
app/src/main/java/org/mozilla/fenix/tor/SecurityLevel.kt
=====================================
@@ -0,0 +1,51 @@
+/* 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
+
+ at 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")
+        }
+    }
+}


=====================================
app/src/main/res/layout/tor_onboarding_security_level.xml
=====================================
@@ -37,7 +37,7 @@
 
 
     <org.mozilla.fenix.onboarding.OnboardingRadioButton
-        android:id="@+id/security_level_standard_default"
+        android:id="@+id/security_level_standard_option"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginStart="16dp"
@@ -52,9 +52,9 @@
         android:theme="@style/Checkable.Colored"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/description_text"
-        app:onboardingKey="@string/pref_key_tor_security_level_standard_default"
-        app:onboardingKeyDescription="@string/tor_onboarding_security_level_standard_button_description"
-        app:onboardingKeyTitle="@string/tor_onboarding_security_level_standard_option"
+        app:onboardingKey="@string/pref_key_tor_security_level_standard_option"
+        app:onboardingKeyDescription="@string/tor_security_level_standard_description"
+        app:onboardingKeyTitle="@string/tor_security_level_standard_option"
         tools:text="Standard" />
 
     <org.mozilla.fenix.onboarding.OnboardingRadioButton
@@ -73,10 +73,10 @@
         android:textColor="@color/primary_state_list_text_color"
         android:theme="@style/Checkable.Colored"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/security_level_standard_default"
+        app:layout_constraintTop_toBottomOf="@id/security_level_standard_option"
         app:onboardingKey="@string/pref_key_tor_security_level_safer_option"
-        app:onboardingKeyDescription="@string/tor_onboarding_security_level_safer_button_description"
-        app:onboardingKeyTitle="@string/tor_onboarding_security_level_safer_option"
+        app:onboardingKeyDescription="@string/tor_security_level_safer_description"
+        app:onboardingKeyTitle="@string/tor_security_level_safer_option"
         tools:text="Safer" />
 
     <org.mozilla.fenix.onboarding.OnboardingRadioButton
@@ -97,8 +97,8 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/security_level_safer_option"
         app:onboardingKey="@string/pref_key_tor_security_level_safest_option"
-        app:onboardingKeyDescription="@string/tor_onboarding_security_level_safest_button_description"
-        app:onboardingKeyTitle="@string/tor_onboarding_security_level_safest_option"
+        app:onboardingKeyDescription="@string/tor_security_level_safest_description"
+        app:onboardingKeyTitle="@string/tor_security_level_safest_option"
         tools:text="Safest" />
 
     <Button


=====================================
app/src/main/res/navigation/nav_graph.xml
=====================================
@@ -58,6 +58,9 @@
     <action
         android:id="@+id/action_global_syncedTabsFragment"
         app:destination="@id/syncedTabsFragment" />
+    <action
+        android:id="@+id/action_global_torSecurityLevelFragment"
+        app:destination="@id/torSecurityLevelFragment" />
     <action
         android:id="@+id/action_global_privateBrowsingFragment"
         app:destination="@id/privateBrowsingFragment" />
@@ -496,6 +499,13 @@
             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_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"
@@ -655,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"


=====================================
app/src/main/res/values/preference_keys.xml
=====================================
@@ -223,10 +223,10 @@
     <string name="pref_key_noscript_installed" translatable="false">pref_key_noscript_installed</string>
 
     <!-- Security Level Settings -->
-    <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_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_tor_security_level_custom_option" translatable="false">pref_key_tor_security_level_custom_option</string>
 
     <string name="pref_key_tor_network_settings" translatable="false">pref_key_tor_network_settings</string>
     <string name="pref_key_tor_network_settings_explanation" translatable="false">pref_key_tor_network_settings_explanation</string>


=====================================
app/src/main/res/values/torbrowser_strings.xml
=====================================
@@ -20,12 +20,6 @@
 
     <string name="tor_onboarding_security_level">Set your Security Level</string>
     <string name="tor_onboarding_security_level_description">Disable certain web features that can be used to attack you, and harm your security, anonymity, and privacy.</string>
-    <string name="tor_onboarding_security_level_standard_option">Standard</string>
-    <string name="tor_onboarding_security_level_standard_button_description">All Tor Browser and website features are enabled.</string>
-    <string name="tor_onboarding_security_level_safer_option">Safer</string>
-    <string name="tor_onboarding_security_level_safer_button_description">Disable website features that are often dangerous, causing some sites to lose functionality.</string>
-    <string name="tor_onboarding_security_level_safest_option">Safest</string>
-    <string name="tor_onboarding_security_level_safest_button_description">Only allow website features required for static sites and basic services. These changes affect images, media, and scripts.</string>
     <string name="tor_onboarding_security_settings_button">Open Security Settings</string>
     <string name="tor_onboarding_donate_header">Donate and keep Tor safe</string>
     <string name="tor_onboarding_donate_description">Tor is free to use because of donations from people like you.</string>
@@ -59,4 +53,17 @@
     <string name="preferences_tor_network_settings_connected">Connected</string>
     <string name="preferences_tor_network_settings_restarting">Restarting</string>
     <string name="preferences_tor_network_settings_bridges_enabled">Bridges are enabled: %s</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>
+
+    <!-- Description of security levels -->
+    <string name="tor_security_level_standard_option">Standard</string>
+    <string name="tor_security_level_standard_description">All Tor Browser and website features are enabled.</string>
+    <string name="tor_security_level_safer_option">Safer</string>
+    <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>
+
 </resources>


=====================================
app/src/main/res/xml/preferences.xml
=====================================
@@ -90,6 +90,11 @@
         app:iconSpaceReserved="false"
         android:layout="@layout/preference_category_main_style">
 
+        <androidx.preference.Preference
+            android:icon="@drawable/ic_tracking_protection_enabled"
+            android:key="@string/pref_key_tor_security_level_settings"
+            android:title="@string/preferences_tor_security_level_settings"/>
+
         <androidx.preference.Preference
             android:icon="@drawable/ic_private_browsing"
             android:key="@string/pref_key_private_browsing"


=====================================
app/src/main/res/xml/tor_security_level_preferences.xml
=====================================
@@ -0,0 +1,21 @@
+<?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>



View it on GitLab: https://gitlab.torproject.org/tpo/applications/fenix/-/compare/74d5540329f4a697000d1416f9d8b9fb450e8cec...d7f419b356f4705a2841d42cfda3ef682cf4e825

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/fenix/-/compare/74d5540329f4a697000d1416f9d8b9fb450e8cec...d7f419b356f4705a2841d42cfda3ef682cf4e825
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tor-commits/attachments/20201001/2783499c/attachment-0001.htm>


More information about the tor-commits mailing list