Pier Angelo Vendrame pushed to branch firefox-android-115.2.1-13.5-1 at The Tor Project / Applications / firefox-android
Commits: 48593938 by clairehurst at 2023-12-21T14:48:46-07:00 Enable the connect assist experiments on alpha
- - - - -
13 changed files:
- android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt - android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/Settings.kt - fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt - fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt - fenix/app/src/main/java/org/mozilla/fenix/settings/TorNetworkSettingsFragment.kt - + fenix/app/src/main/java/org/mozilla/fenix/tor/TorBetaConnectionFeaturesFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt - + fenix/app/src/main/res/layout/tor_network_settings_beta_connection_features.xml - fenix/app/src/main/res/navigation/nav_graph.xml - fenix/app/src/main/res/values/preference_keys.xml - fenix/app/src/main/res/xml/tor_network_settings_preferences.xml
Changes:
===================================== android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt ===================================== @@ -799,6 +799,11 @@ class GeckoEngine( override var prioritizeOnions: Boolean get() = runtime.settings.prioritizeOnions set(value) { runtime.settings.prioritizeOnions = value } + override var useNewBootstrap: Boolean + get() = runtime.settings.useNewBootstrap + set(value) { + runtime.settings.useNewBootstrap = value + } }.apply { defaultSettings?.let { this.javascriptEnabled = it.javascriptEnabled @@ -824,6 +829,7 @@ class GeckoEngine( this.torSecurityLevel = it.torSecurityLevel this.spoofEnglish = it.spoofEnglish this.prioritizeOnions = it.prioritizeOnions + this.useNewBootstrap = it.useNewBootstrap } }
@@ -929,6 +935,8 @@ class GeckoEngine( unBlockedBySmartBlock = this.blockingData.any { it.unBlockedBySmartBlock() }, ) } + + fun getTorIntegrationController() = runtime.getTorIntegrationController() }
internal fun ContentBlockingController.LogEntry.BlockingData.hasBlockedCookies(): Boolean {
===================================== android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/Settings.kt ===================================== @@ -214,6 +214,8 @@ abstract class Settings { open var spoofEnglish: Boolean by UnsupportedSetting()
open var prioritizeOnions: Boolean by UnsupportedSetting() + + open var useNewBootstrap: Boolean by UnsupportedSetting() }
/** @@ -259,6 +261,7 @@ data class DefaultSettings( override var torSecurityLevel: Int = 4, override var spoofEnglish: Boolean = false, override var prioritizeOnions: Boolean = false, + override var useNewBootstrap: Boolean = false, ) : Settings()
class UnsupportedSetting<T> {
===================================== fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt ===================================== @@ -164,6 +164,11 @@ import org.mozilla.fenix.utils.Settings import java.lang.ref.WeakReference import java.util.Locale
+import androidx.navigation.fragment.findNavController +import mozilla.components.browser.engine.gecko.GeckoEngine +import mozilla.components.browser.state.selector.findCustomTab +import org.mozilla.geckoview.TorIntegrationAndroid + /** * The main activity of the application. The application is primarily a single Activity (this one) * with fragments switching out to display different views. The most important views shown here are the: @@ -171,7 +176,7 @@ import java.util.Locale * - browser screen */ @SuppressWarnings("TooManyFunctions", "LargeClass", "LongParameterList", "LongMethod") -open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { +open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorIntegrationAndroid.BootstrapStateChangeListener { // DO NOT MOVE ANYTHING ABOVE THIS, GETTING INIT TIME IS CRITICAL // we need to store startup timestamp for warm startup. we cant directly store // inside AppStartupTelemetry since that class lives inside components and @@ -201,7 +206,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
private var inflater: LayoutInflater? = null
- private val navHost by lazy { + val navHost by lazy { supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment }
@@ -396,6 +401,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
components.notificationsDelegate.bindToActivity(this)
+ val engine = components.core.engine + if (engine is GeckoEngine) { + val torIntegration = engine.getTorIntegrationController() + torIntegration.registerBootstrapStateChangeListener(this) + } + StartupTimeline.onActivityCreateEndHome(this) // DO NOT MOVE ANYTHING BELOW HERE. }
@@ -609,6 +620,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { // underlying Application, as well. (application as FenixApplication).terminate() } + + val engine = components.core.engine + if (engine is GeckoEngine) { + val torIntegration = engine.getTorIntegrationController() + torIntegration.unregisterBootstrapStateChangeListener(this) + } }
override fun onConfigurationChanged(newConfig: Configuration) { @@ -1163,7 +1180,20 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { }
open fun navigateToHome() { - navHost.navController.navigate(NavGraphDirections.actionStartupTorbootstrap()) + if (settings().useNewBootstrap) { + if (settings().useNewBootstrapNativeUi) { + navHost.navController.navigate(NavGraphDirections.actionStartupTorConnectionAssist()) + } else { + navHost.navController.navigate(NavGraphDirections.actionStartupHome()) + openToBrowserAndLoad( + searchTermOrURL = "about:torconnect", + newTab = true, + from = BrowserDirection.FromHome, + ) + } + } else { + navHost.navController.navigate(NavGraphDirections.actionStartupTorbootstrap()) + } }
override fun attachBaseContext(base: Context) { @@ -1341,4 +1371,15 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { // telemetry purposes. const val PWA_RECENTLY_USED_THRESHOLD = DateUtils.DAY_IN_MILLIS * 30L } + + override fun onBootstrapStateChange(state: String) = Unit + override fun onBootstrapProgress(progress: Double, status: String, hasWarnings: Boolean) = Unit + override fun onBootstrapComplete() { + components.useCases.tabsUseCases.removeAllTabs() + navHost.navController.navigate(NavGraphDirections.actionStartupHome()) + } + override fun onBootstrapError(message: String, details: String) = Unit + override fun onSettingsRequested() { + navHost.navController.navigate(NavGraphDirections.actionGlobalSettingsFragment()) + } }
===================================== fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt ===================================== @@ -1189,6 +1189,9 @@ abstract class BaseBrowserFragment : val context = requireContext() resumeDownloadDialogState(selectedTab.id, context.components.core.store, context, toolbarHeight) it.announceForAccessibility(selectedTab.toDisplayTitle()) + if (getCurrentTab()?.content?.url == "about:torconnect") { + browserToolbarView.view.visibility = View.GONE + } } } else { view?.let { view -> initializeUI(view) } @@ -1206,6 +1209,24 @@ abstract class BaseBrowserFragment : components.useCases.sessionUseCases.reload() } hideToolbar() + handleBetaHtmlTorConnect() + } + + private fun handleBetaHtmlTorConnect() { + if (getCurrentTab()?.content?.url == "about:torconnect") { + if (!requireActivity().settings().useNewBootstrap) { + requireContext().components.useCases.tabsUseCases.removeAllTabs() + (requireActivity() as HomeActivity).navHost.navController.navigate( + NavGraphDirections.actionStartupTorbootstrap(), + ) + } else if (!requireActivity().settings().useNewBootstrapHtmlUi) { + requireContext().components.useCases.tabsUseCases.removeAllTabs() + (requireActivity() as HomeActivity).navigateToHome() + } else { + // This just makes it not flash (be visible for a split second) before handleTabSelected() hides it again + browserToolbarView.view.visibility = View.GONE + } + } }
@CallSuper
===================================== fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt ===================================== @@ -146,6 +146,7 @@ class Core( torSecurityLevel = context.settings().torSecurityLevel().intRepresentation, spoofEnglish = context.settings().spoofEnglish, prioritizeOnions = context.settings().prioritizeOnions, + useNewBootstrap = context.settings().useNewBootstrap, )
GeckoEngine(
===================================== fenix/app/src/main/java/org/mozilla/fenix/settings/TorNetworkSettingsFragment.kt ===================================== @@ -76,6 +76,15 @@ class TorNetworkSettingsFragment : PreferenceFragmentCompat(), TorEvents { } }
+ requirePreference<Preference>(R.string.pref_key_use_new_bootstrap).apply { + setOnPreferenceClickListener { + val directions = + TorNetworkSettingsFragmentDirections.actionTorNetworkSettingsFragmentToBetaConnectionFeaturesFragment() + requireView().findNavController().navigate(directions) + true + } + } + setStatus() }
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorBetaConnectionFeaturesFragment.kt ===================================== @@ -0,0 +1,69 @@ +/* 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.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.view.children +import androidx.fragment.app.Fragment +import org.mozilla.fenix.databinding.TorNetworkSettingsBetaConnectionFeaturesBinding +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings + +/** + * Lets the user customize beta connection features mode. + */ +class TorBetaConnectionFeaturesFragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + val binding = TorNetworkSettingsBetaConnectionFeaturesBinding.inflate(inflater) + + binding.enableBetaConnectionFeaturesSwitch.run { + isChecked = context.settings().useNewBootstrap + setConnectionAssistUI(binding, isChecked) + + setOnCheckedChangeListener { _, isConnectionAssistEnabled -> + context.settings().useNewBootstrap = isConnectionAssistEnabled + setConnectionAssistUI(binding, isConnectionAssistEnabled) + updateEngineConnectionAssistMode() + } + } + + // Since the beta connection features modes are in a RadioGroup we only need one listener to know of all their changes. + binding.useNewBootstrapWithNativeUiRadioButton.setOnCheckedChangeListener { _, _ -> + updateEngineConnectionAssistMode() + } + + return binding.root + } + + private fun setConnectionAssistUI( + binding: TorNetworkSettingsBetaConnectionFeaturesBinding, + isBetaConnectionAssistEnabled: Boolean, + ) { + if (!isBetaConnectionAssistEnabled) { + binding.enableBetaConnectionFeaturesModes.apply { + clearCheck() + children.forEach { it.isEnabled = false } + } + } else { + // Do not enable the native UI until it is actually available. + // binding.enableBetaConnectionFeaturesModes.children.forEach { it.isEnabled = true } + binding.useNewBootstrapWithHtmlUiRadioButton.isEnabled = true + binding.useNewBootstrapWithNativeUiRadioButton.isEnabled = false + } + } + + private fun updateEngineConnectionAssistMode() { + requireContext().components.core.engine.settings.useNewBootstrap = + requireContext().settings().useNewBootstrap + } + +}
===================================== fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt ===================================== @@ -20,8 +20,10 @@ import org.mozilla.fenix.tor.interactor.DefaultTorBootstrapInteractor import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor import androidx.navigation.fragment.findNavController import com.google.android.material.appbar.AppBarLayout +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.hideToolbar +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.tor.controller.DefaultTorBootstrapController import org.mozilla.fenix.tor.view.TorBootstrapView
@@ -169,6 +171,9 @@ class TorBootstrapFragment : Fragment() { // triggered to cause an automatic update on warm start (no tab selection occurs). So we // update it manually here. requireComponents.useCases.sessionUseCases.updateLastAccess() + if (requireContext().settings().useNewBootstrap){ + (requireActivity() as HomeActivity).navigateToHome() + } }
private fun handleTorBootstrapConnect() {
===================================== fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt ===================================== @@ -1859,4 +1859,19 @@ class Settings(private val appContext: Context) : PreferencesHolder { * Indicates if the new Search settings UI is enabled. */ var enableUnifiedSearchSettingsUI: Boolean = showUnifiedSearchFeature && FeatureFlags.unifiedSearchSettings + + var useNewBootstrap by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_use_new_bootstrap), + default = false, + ) + + var useNewBootstrapNativeUi by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_use_new_bootstrap_with_android_native), + default = false, + ) + + var useNewBootstrapHtmlUi by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_use_new_bootstrap_with_html), + default = true + ) }
===================================== fenix/app/src/main/res/layout/tor_network_settings_beta_connection_features.xml ===================================== @@ -0,0 +1,100 @@ +<?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="wrap_content"> + + <TextView + android:id="@+id/enable_beta_connection_features_title" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:layout_marginBottom="2dp" + android:clickable="false" + android:text="Enable beta connection features" + android:textAppearance="@style/ListItemTextStyle" + android:textSize="16sp" + app:layout_constraintBottom_toTopOf="@id/enable_beta_connection_features_summary" + app:layout_constraintEnd_toStartOf="@id/enable_beta_connection_features_switch" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:lineHeight="24.sp" /> + + <TextView + android:id="@+id/enable_beta_connection_features_summary" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:text="Help us test our new connection assist features which focuses on a streamlined connection with better integration with bridges" + android:textColor="?attr/textSecondary" + android:textColorLink="?attr/textSecondary" + android:textSize="12sp" + app:layout_constraintBottom_toTopOf="@id/enable_beta_connection_features_modes" + app:layout_constraintEnd_toEndOf="@id/enable_beta_connection_features_title" + app:layout_constraintStart_toStartOf="@id/enable_beta_connection_features_title" + app:layout_constraintTop_toBottomOf="@id/enable_beta_connection_features_title" + app:lineHeight="16.sp" /> + + <androidx.appcompat.widget.SwitchCompat + android:id="@+id/enable_beta_connection_features_switch" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minHeight="48dp" + android:paddingStart="18dp" + android:paddingEnd="18dp" + android:textColor="@color/state_list_text_color" + android:textOff="@string/studies_off" + android:textOn="@string/studies_on" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@id/enable_beta_connection_features_title" /> + + <RadioGroup + android:id="@+id/enable_beta_connection_features_modes" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/enable_beta_connection_features_summary"> + + <org.mozilla.fenix.settings.PreferenceBackedRadioButton + android:id="@+id/use_new_bootstrap_with_html_ui_radio_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:button="@null" + android:drawablePadding="@dimen/radio_button_preference_drawable_padding" + android:paddingStart="@dimen/radio_button_preference_horizontal" + android:paddingTop="@dimen/radio_button_preference_vertical" + android:paddingEnd="@dimen/radio_button_preference_horizontal" + android:paddingBottom="@dimen/radio_button_preference_vertical" + android:text="HTML UI" + android:textAppearance="?android:attr/textAppearanceListItem" + android:textSize="16sp" + app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle" + app:preferenceKey="@string/pref_key_use_new_bootstrap_with_html" + app:preferenceKeyDefaultValue="true" /> + + <org.mozilla.fenix.settings.PreferenceBackedRadioButton + android:id="@+id/use_new_bootstrap_with_native_ui_radio_button" + android:layout_width="match_parent" + android:layout_height="48dp" + android:background="?android:attr/selectableItemBackground" + android:button="@null" + android:drawablePadding="@dimen/radio_button_preference_drawable_padding" + android:enabled="false" + android:paddingStart="@dimen/radio_button_preference_horizontal" + android:paddingTop="@dimen/radio_button_preference_vertical" + android:paddingEnd="@dimen/radio_button_preference_horizontal" + android:paddingBottom="@dimen/radio_button_preference_vertical" + android:text="Native Android UI" + android:textAppearance="?android:attr/textAppearanceListItem" + android:textSize="16sp" + app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle" + app:preferenceKey="@string/pref_key_use_new_bootstrap_with_android_native" + app:preferenceKeyDefaultValue="false" /> + </RadioGroup> + +</androidx.constraintlayout.widget.ConstraintLayout>
===================================== fenix/app/src/main/res/navigation/nav_graph.xml ===================================== @@ -27,6 +27,12 @@ app:popUpTo="@id/startupFragment" app:popUpToInclusive="true" />
+ <action + android:id="@+id/action_startup_tor_connection_assist" + app:destination="@+id/torConnectionAssistFragment" + app:popUpTo="@id/startupFragment" + app:popUpToInclusive="true" /> + <action android:id="@+id/action_global_home" app:destination="@id/homeFragment" @@ -941,12 +947,25 @@ app:exitAnim="@anim/slide_out_left" app:popEnterAnim="@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" /> + <action + android:id="@+id/action_torNetworkSettingsFragment_to_BetaConnectionFeaturesFragment" + app:destination="@+id/torBetaConnectionFeaturesFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> </fragment> <fragment android:id="@+id/torBridgeConfigFragment" android:name="org.mozilla.fenix.settings.TorBridgeConfigFragment" android:label="@string/preferences_tor_network_settings_bridge_config" tools:layout="@layout/fragment_tor_bridge_config" /> + <fragment + android:id="@+id/torBetaConnectionFeaturesFragment" + android:name="org.mozilla.fenix.tor.TorBetaConnectionFeaturesFragment" + android:label="Enable beta connection features" + tools:layout="@layout/tor_network_settings_beta_connection_features" /> + <fragment android:id="@+id/trackingProtectionFragment" android:name="org.mozilla.fenix.settings.TrackingProtectionFragment">
===================================== fenix/app/src/main/res/values/preference_keys.xml ===================================== @@ -376,6 +376,9 @@ <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> <string name="pref_key_tor_network_settings_bridge_config" translatable="false">pref_key_tor_network_settings_bridge_config</string> + <string name="pref_key_use_new_bootstrap" translatable="false">pref_key_use_new_bootstrap</string> + <string name="pref_key_use_new_bootstrap_with_android_native" translatable="false">pref_key_use_new_bootstrap_with_android_native</string> + <string name="pref_key_use_new_bootstrap_with_html" translatable="false">pref_key_use_new_bootstrap_with_html</string> <string name="pref_key_tor_network_settings_bridge_config_explanation" translatable="false">pref_key_tor_network_settings_bridge_config_explanation</string> <string name="pref_key_tor_network_settings_bridge_config_toggle" translatable="false">pref_key_tor_network_settings_bridge_config_toggle</string> <string name="pref_key_tor_network_settings_bridge_config_builtin_bridge_obfs4" translatable="false">pref_key_tor_network_settings_bridge_config_builtin_bridge_obfs4</string>
===================================== fenix/app/src/main/res/xml/tor_network_settings_preferences.xml ===================================== @@ -27,4 +27,9 @@ android:title="@string/preferences_tor_network_settings_bridge_config" android:summary="@string/preferences_tor_network_settings_bridge_config_description" app:allowDividerAbove="true" /> + <Preference + android:key="@string/pref_key_use_new_bootstrap" + android:title="Enable beta connection features" + app:allowDividerAbove="true" /> + </androidx.preference.PreferenceScreen>
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/4859...