tbb-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 18700 discussions

[Git][tpo/applications/firefox-android] Pushed new tag firefox-android-115.2.1-13.0-1-build2
by Dan Ballard (@dan) 12 Sep '23
by Dan Ballard (@dan) 12 Sep '23
12 Sep '23
Dan Ballard pushed new tag firefox-android-115.2.1-13.0-1-build2 at The Tor Project / Applications / firefox-android
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/tree/firef…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.0-1] fixup! Disable features and functionality
by Dan Ballard (@dan) 12 Sep '23
by Dan Ballard (@dan) 12 Sep '23
12 Sep '23
Dan Ballard pushed to branch firefox-android-115.2.1-13.0-1 at The Tor Project / Applications / firefox-android
Commits:
2ed6053c by Dan Ballard at 2023-09-12T09:06:04-07:00
fixup! Disable features and functionality
Bug 42001: Hide 'Open links in external app' settings option and force defaults
- - - - -
5 changed files:
- fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
- fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
- fenix/app/src/main/res/navigation/nav_graph.xml
- fenix/app/src/main/res/xml/preferences.xml
Changes:
=====================================
fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
=====================================
@@ -848,7 +848,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
clipboardSuggestionsEnabled.set(settings.shouldShowClipboardSuggestions)
searchShortcutsEnabled.set(settings.shouldShowSearchShortcuts)
voiceSearchEnabled.set(settings.shouldShowVoiceSearch)
- openLinksInAppEnabled.set(settings.openLinksInExternalApp)
+ //openLinksInAppEnabled.set(settings.openLinksInExternalApp)
signedInSync.set(settings.signedInFxaAccount)
val syncedItems = SyncEnginesStorage(applicationContext).getStatus().entries.filter {
=====================================
fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
=====================================
@@ -234,9 +234,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
getString(R.string.preferences_credit_cards)
}
+ /*
val openLinksInAppsSettingsPreference =
requirePreference<Preference>(R.string.pref_key_open_links_in_apps)
openLinksInAppsSettingsPreference.summary = context?.settings()?.getOpenLinksInAppsString()
+ */
// Hide "Delete browsing data on quit" when in Private Browsing-only mode
deleteBrowsingDataPreference.isVisible =
@@ -308,9 +310,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
Addons.openAddonsInSettings.record(mozilla.components.service.glean.private.NoExtras())
SettingsFragmentDirections.actionSettingsFragmentToAddonsFragment()
}
+ /*
resources.getString(R.string.pref_key_open_links_in_apps) -> {
SettingsFragmentDirections.actionSettingsFragmentToOpenLinksInAppsFragment()
}
+ */
resources.getString(R.string.pref_key_data_choices) -> {
SettingsFragmentDirections.actionSettingsFragmentToDataChoicesFragment()
}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
=====================================
@@ -599,6 +599,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
/**
* Get the display string for the current open links in apps setting
*/
+ /*
fun getOpenLinksInAppsString(): String =
when (openLinksInExternalApp) {
appContext.getString(R.string.pref_key_open_links_in_apps_always) -> {
@@ -615,6 +616,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
appContext.getString(R.string.preferences_open_links_in_apps_never)
}
}
+ */
var shouldUseDarkTheme by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_dark_theme),
@@ -1298,26 +1300,31 @@ class Settings(private val appContext: Context) : PreferencesHolder {
/**
* Check to see if we should open the link in an external app
*/
+ @Suppress("UNUSED_PARAMETER")
fun shouldOpenLinksInApp(isCustomTab: Boolean = false): Boolean {
- return when (openLinksInExternalApp) {
- appContext.getString(R.string.pref_key_open_links_in_apps_always) -> true
- appContext.getString(R.string.pref_key_open_links_in_apps_ask) -> true
+ return false
+ //return when (openLinksInExternalApp) {
+ // appContext.getString(R.string.pref_key_open_links_in_apps_always) -> true
+ // appContext.getString(R.string.pref_key_open_links_in_apps_ask) -> true
/* Some applications will not work if custom tab never open links in apps, return true if it's custom tab */
- appContext.getString(R.string.pref_key_open_links_in_apps_never) -> isCustomTab
- else -> false
- }
+ // appContext.getString(R.string.pref_key_open_links_in_apps_never) -> isCustomTab
+ //else -> false
+ //}
}
/**
* Check to see if we need to prompt the user if the link can be opened in an external app
*/
fun shouldPromptOpenLinksInApp(): Boolean {
+ return true
+ /*
return when (openLinksInExternalApp) {
appContext.getString(R.string.pref_key_open_links_in_apps_always) -> false
appContext.getString(R.string.pref_key_open_links_in_apps_ask) -> true
appContext.getString(R.string.pref_key_open_links_in_apps_never) -> true
else -> true
}
+ */
}
var openLinksInExternalApp by stringPreference(
=====================================
fenix/app/src/main/res/navigation/nav_graph.xml
=====================================
@@ -723,6 +723,7 @@
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_openLinksInAppsFragment"
app:destination="@id/openLinksInAppsFragment"
@@ -730,6 +731,7 @@
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_tabsSettingsFragment"
app:destination="@id/tabsSettingsFragment"
@@ -963,9 +965,11 @@
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
+ <!--
<fragment
android:id="@+id/openLinksInAppsFragment"
android:name="org.mozilla.fenix.settings.OpenLinksInAppsFragment" />
+ -->
<fragment
android:id="@+id/deleteBrowsingDataFragment"
android:name="org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataFragment"
=====================================
fenix/app/src/main/res/xml/preferences.xml
=====================================
@@ -180,12 +180,12 @@
android:key="@string/pref_key_override_amo_collection"
app:iconSpaceReserved="false"
android:title="@string/preferences_customize_amo_collection" />
-
+ <!--
<androidx.preference.Preference
android:key="@string/pref_key_open_links_in_apps"
android:title="@string/preferences_open_links_in_apps"
app:iconSpaceReserved="false" />
-
+ -->
<androidx.preference.SwitchPreference
android:defaultValue="false"
android:key="@string/pref_key_external_download_manager"
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/2ed…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/commit/2ed…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.0-1] 3 commits: fixup! Add Tor integration and UI
by Dan Ballard (@dan) 12 Sep '23
by Dan Ballard (@dan) 12 Sep '23
12 Sep '23
Dan Ballard pushed to branch firefox-android-115.2.1-13.0-1 at The Tor Project / Applications / firefox-android
Commits:
a09967fd by Dan Ballard at 2023-09-12T08:52:55-07:00
fixup! Add Tor integration and UI
Bug 41878: Remove bootstrap from `Add Tor integration and UI`
- - - - -
40bf5511 by Dan Ballard at 2023-09-12T08:52:55-07:00
fixup! Add Tor integration and UI
Bug 41878: Remove rest of onboarding from `Add Tor integration and UI`
- - - - -
d2a7dfa6 by Dan Ballard at 2023-09-12T08:52:55-07:00
Bug 41878: Add standalone Tor Bootstrap
- - - - -
25 changed files:
- fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/Mode.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
- − fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingDonateViewHolder.kt
- − fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/controller/TorBootstrapController.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/interactor/TorBootstrapInteractor.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapAdapter.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapConnectViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapLoggerViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapLoggerViewHolder.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/torbootstrap/BootstrapPagerAdapter.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerAdapter.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapPagerViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerViewHolder.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapView.kt
- − fenix/app/src/main/res/drawable/tor_onboarding_donate_gradient.xml
- − fenix/app/src/main/res/drawable/tor_onboarding_donate_rounded_corners.xml
- − fenix/app/src/main/res/layout/tor_onboarding_donate.xml
- − fenix/app/src/main/res/layout/tor_onboarding_security_level.xml
- fenix/app/src/main/res/navigation/nav_graph.xml
- fenix/app/src/main/res/values/styles.xml
Changes:
=====================================
fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
=====================================
@@ -34,6 +34,7 @@ import androidx.annotation.VisibleForTesting.Companion.PROTECTED
import androidx.appcompat.app.ActionBar
import androidx.appcompat.widget.Toolbar
import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.ContentProviderCompat.requireContext
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavDestination
import androidx.navigation.NavDirections
@@ -285,6 +286,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
it.start()
}
+ /*
if (settings().shouldShowJunoOnboarding(
hasUserBeenOnboarded = components.fenixOnboarding.userHasBeenOnboarded(),
isLauncherIntent = intent.toSafeIntent().isLauncherIntent,
@@ -295,6 +297,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
navHost.navController.navigate(NavGraphDirections.actionGlobalJunoOnboarding())
}
} else {
+ */
lifecycleScope.launch(IO) {
// showFullscreenMessageIfNeeded(applicationContext)
}
@@ -315,7 +318,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
showNotificationPermissionPromptIfRequired()
*/
- }
+ //}
Performance.processIntentIfPerformanceTest(intent, this)
@@ -1158,13 +1161,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
open fun navigateToHome() {
- // if (components.fenixOnboarding.userHasBeenOnboarded()) {
- navHost.navController.navigate(NavGraphDirections.actionStartupHome())
- /*
- } else {
- navHost.navController.navigate(NavGraphDirections.actionStartupOnboarding())
- }
- */
+ navHost.navController.navigate(NavGraphDirections.actionStartupTorbootstrap())
}
override fun attachBaseContext(base: Context) {
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
=====================================
@@ -113,6 +113,8 @@ import org.mozilla.fenix.perf.runBlockingIncrement
import org.mozilla.fenix.search.toolbar.DefaultSearchSelectorController
import org.mozilla.fenix.search.toolbar.SearchSelectorMenu
import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
+import org.mozilla.fenix.tor.TorBootstrapFragmentDirections
+import org.mozilla.fenix.tor.TorBootstrapStatus
import org.mozilla.fenix.tor.bootstrap.TorQuickStart
import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
import org.mozilla.fenix.utils.allowUndo
@@ -200,9 +202,9 @@ class HomeFragment : Fragment() {
private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>()
private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>()
private val searchSelectorBinding = ViewBoundFeatureWrapper<SearchSelectorBinding>()
- private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
private val torQuickStart by lazy { TorQuickStart(requireContext()) }
- private lateinit var currentMode: CurrentMode
+ private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
+ private lateinit var torBootstrapStatus: TorBootstrapStatus
override fun onCreate(savedInstanceState: Bundle?) {
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
@@ -233,29 +235,27 @@ class HomeFragment : Fragment() {
val activity = activity as HomeActivity
val components = requireComponents
- val currentWallpaperName = requireContext().settings().currentWallpaperName
- applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false)
-
- currentMode = CurrentMode(
- requireContext(),
+ torBootstrapStatus = TorBootstrapStatus(
torQuickStart,
!BuildConfig.DISABLE_TOR,
components.torController,
- browsingModeManager,
::dispatchModeChanges
)
+ val currentWallpaperName = requireContext().settings().currentWallpaperName
+ applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false)
+
// Splits by full stops or commas and puts the parts in different lines.
// Ignoring separators at the end of the string, it is expected
// that there are at most two parts (e.g. "Explore. Privately.").
- val localBinding = binding;
+ val localBinding = binding
binding.exploreprivately.text = localBinding
.exploreprivately
.text
?.replace(" *([.,。।]) *".toRegex(), "$1\n")
?.trim()
- components.appStore.dispatch(AppAction.ModeChange(currentMode.getCurrentMode()))
+ components.appStore.dispatch(AppAction.ModeChange(Mode.fromBrowsingMode(browsingModeManager.mode)))
lifecycleScope.launch(IO) {
if (requireContext().settings().showPocketRecommendationsFeature) {
@@ -378,10 +378,6 @@ class HomeFragment : Fragment() {
registerCollectionStorageObserver = ::registerCollectionStorageObserver,
removeCollectionWithUndo = ::removeCollectionWithUndo,
showTabTray = ::openTabsTray,
- handleTorBootstrapConnect = ::handleTorBootstrapConnect,
- cancelTorBootstrap = ::cancelTorBootstrap,
- initiateTorBootstrap = ::initiateTorBootstrap,
- openTorNetworkSettings = ::openTorNetworkSettings
),
recentTabController = DefaultRecentTabsController(
selectTabUseCase = components.useCases.tabsUseCases.selectTab,
@@ -447,9 +443,6 @@ class HomeFragment : Fragment() {
FxNimbus.features.homescreen.recordExposure()
- adjustHomeFragmentView(currentMode.getCurrentMode())
- showSessionControlView()
-
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
requireComponents.core.engine.profiler?.addMarker(
MarkersFragmentLifecycleCallbacks.MARKER_NAME,
@@ -530,111 +523,6 @@ class HomeFragment : Fragment() {
binding.homeAppBar.setExpanded(true)
}
- // This function should be paired with showSessionControlView()
- @SuppressWarnings("ComplexMethod", "NestedBlockDepth", "LongMethod")
- private fun adjustHomeFragmentView(mode: Mode) {
- binding.sessionControlRecyclerView.apply {
- visibility = View.INVISIBLE
- }
-
- if (mode == Mode.Bootstrap) {
- binding.sessionControlRecyclerView.apply {
- setPadding(0, 0, 0, 0)
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(0, 0, 0, 0)
- }
- binding.homeAppBar.apply {
- visibility = View.GONE
-
- // Reset this as SCROLL in case it was previously set as NO_SCROLL after bootstrap
- children.forEach {
- (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
- AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
- }
- }
- binding.onionPatternImage.apply {
- visibility = View.GONE
- }
- binding.toolbarLayout.apply {
- visibility = View.GONE
- }
- } else {
- // Keep synchronized with xml layout (somehow).
- binding.sessionControlRecyclerView.apply {
- setPadding(
- SESSION_CONTROL_VIEW_PADDING,
- SESSION_CONTROL_VIEW_PADDING,
- SESSION_CONTROL_VIEW_PADDING,
- SESSION_CONTROL_VIEW_PADDING
- )
- // Default margin until it is re-set below (either set immediately or after Layout)
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
- 0,
- 0,
- 0,
- DEFAULT_ONBOARDING_FINISH_MARGIN
- )
- }
- binding.toolbarLayout.apply {
- visibility = View.VISIBLE
- // If the Layout rendering pass was completed, then we have a |height| value,
- // if it wasn't completed then we have 0.
- if (height == 0) {
- // Set the bottom margin after the toolbar height is defined during Layout
- doOnLayout {
- val toolbarLayoutHeight = binding.toolbarLayout.height
- binding.sessionControlRecyclerView.apply {
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
- 0,
- 0,
- 0,
- toolbarLayoutHeight - SESSION_CONTROL_VIEW_PADDING
- )
- }
- }
- } else {
- binding.sessionControlRecyclerView.apply {
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
- 0,
- 0,
- 0,
- height - SESSION_CONTROL_VIEW_PADDING
- )
- }
- }
- }
- // Hide the onion pattern during Onboarding, too.
- // With new onboarding HomeFragment is only reached once onboarding is complete
- binding.onionPatternImage.apply {
- visibility = if (currentMode.getCurrentMode() != Mode.Bootstrap) {
- View.VISIBLE
- } else {
- View.GONE
- }
-
- }
- binding.homeAppBar.apply {
- visibility = View.VISIBLE
-
- children.forEach {
- (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
- if (currentMode.getCurrentMode() != Mode.Bootstrap) {
- AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
- } else {
- AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
- }
-
- }
- }
- }
- }
-
- // This function should be paired with adjustHomeFragmentView()
- private fun showSessionControlView() {
- binding.sessionControlRecyclerView.apply {
- visibility = View.VISIBLE
- }
- }
-
@Suppress("LongMethod", "ComplexMethod")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
@@ -880,13 +768,14 @@ class HomeFragment : Fragment() {
requireComponents.reviewPromptController.promptReview(requireActivity())
}
}
-
- private fun dispatchModeChanges(mode: Mode) {
- requireComponents.appStore.dispatch(AppAction.ModeChange(mode))
- adjustHomeFragmentView(mode)
- updateSessionControlView()
- showSessionControlView()
+ private fun dispatchModeChanges(isBootstrapping: Boolean) {
+ if (isBootstrapping) {
+ val directions =
+ TorBootstrapFragmentDirections
+ .actionStartupTorbootstrap()
+ findNavController().navigate(directions)
+ }
}
@VisibleForTesting
@@ -912,21 +801,16 @@ class HomeFragment : Fragment() {
override fun onStop() {
super.onStop()
- currentMode.unregisterTorListener()
+ torBootstrapStatus.unregisterTorListener()
}
override fun onResume() {
super.onResume()
+ torBootstrapStatus.registerTorListener()
if (browsingModeManager.mode == BrowsingMode.Private) {
activity?.window?.setBackgroundDrawableResource(R.drawable.private_home_background_gradient)
}
- // fenix#40176: Ensure the Home fragment is rendered correctly when we resume.
- val mode = currentMode.getCurrentMode()
- adjustHomeFragmentView(mode)
- updateSessionControlView()
- showSessionControlView()
-
hideToolbar()
// Whenever a tab is selected its last access timestamp is automatically updated by A-C.
@@ -1113,25 +997,6 @@ class HomeFragment : Fragment() {
}
}
- private fun handleTorBootstrapConnect() {
- requireComponents.torController.onTorConnecting()
- }
-
- private fun cancelTorBootstrap() {
- requireComponents.torController.stopTor()
- }
-
- private fun initiateTorBootstrap(withDebugLogging: Boolean = false) {
- requireComponents.torController.initiateTorBootstrap(lifecycleScope, withDebugLogging)
- }
-
- private fun openTorNetworkSettings() {
- val directions =
- HomeFragmentDirections
- .actionHomeFragmentToTorNetworkSettingsFragment()
- findNavController().navigate(directions)
- }
-
companion object {
const val ALL_NORMAL_TABS = "all_normal"
const val ALL_PRIVATE_TABS = "all_private"
@@ -1153,9 +1018,5 @@ class HomeFragment : Fragment() {
// Elevation for undo toasts
internal const val TOAST_ELEVATION = 80f
-
- // Layout
- private const val DEFAULT_ONBOARDING_FINISH_MARGIN = 60
- private const val SESSION_CONTROL_VIEW_PADDING = 16
}
}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/Mode.kt
=====================================
@@ -4,12 +4,7 @@
package org.mozilla.fenix.home
-import android.content.Context
-import org.mozilla.fenix.tor.TorController
-import org.mozilla.fenix.tor.TorEvents
-import org.mozilla.fenix.tor.bootstrap.TorQuickStart
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
-import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
/**
* Describes various states of the home fragment UI.
@@ -17,7 +12,6 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
sealed class Mode {
object Normal : Mode()
object Private : Mode()
- object Bootstrap : Mode()
companion object {
fun fromBrowsingMode(browsingMode: BrowsingMode) = when (browsingMode) {
@@ -26,48 +20,3 @@ sealed class Mode {
}
}
}
-
-@SuppressWarnings("LongParameterList", "TooManyFunctions")
-class CurrentMode(
- private val context: Context,
- private val torQuickStart: TorQuickStart,
- private val shouldStartTor: Boolean,
- private val torController: TorController,
- private val browsingModeManager: BrowsingModeManager,
- private val dispatchModeChanges: (mode: Mode) -> Unit
-) : TorEvents {
-
- init {
- torController.registerTorListener(this)
- }
-
- fun getCurrentMode() = if (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped)) {
- Mode.Bootstrap
- } else {
- Mode.fromBrowsingMode(browsingModeManager.mode)
- }
-
- fun emitModeChanges() {
- dispatchModeChanges(getCurrentMode())
- }
-
- @SuppressWarnings("EmptyFunctionBlock")
- override fun onTorConnecting() {
- }
-
- override fun onTorConnected() {
- dispatchModeChanges(getCurrentMode())
- }
-
- override fun onTorStopped() {
- dispatchModeChanges(getCurrentMode())
- }
-
- @SuppressWarnings("EmptyFunctionBlock")
- override fun onTorStatusUpdate(entry: String?, status: String?) {
- }
-
- fun unregisterTorListener() {
- torController.unregisterTorListener(this)
- }
-}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
=====================================
@@ -34,10 +34,7 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHol
import org.mozilla.fenix.home.sessioncontrol.viewholders.CustomizeHomeButtonViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.NoCollectionsMessageViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder
-import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapPagerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.MessageCardViewHolder
-import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.TorOnboardingSecurityLevelViewHolder
-import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.TorOnboardingDonateViewHolder
import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
import mozilla.components.feature.tab.collections.Tab as ComponentTab
@@ -102,8 +99,6 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
object PrivateBrowsingDescription : AdapterItem(PrivateBrowsingDescriptionViewHolder.LAYOUT_ID)
object NoCollectionsMessage : AdapterItem(NoCollectionsMessageViewHolder.LAYOUT_ID)
- object TorBootstrap : AdapterItem(TorBootstrapPagerViewHolder.LAYOUT_ID)
-
object CollectionHeader : AdapterItem(CollectionHeaderViewHolder.LAYOUT_ID)
data class CollectionItem(
val collection: TabCollection,
@@ -143,9 +138,6 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
object CustomizeHomeButton : AdapterItem(CustomizeHomeButtonViewHolder.LAYOUT_ID)
- object TorOnboardingSecurityLevel : AdapterItem(TorOnboardingSecurityLevelViewHolder.LAYOUT_ID)
- object TorOnboardingDonate : AdapterItem(TorOnboardingDonateViewHolder.LAYOUT_ID)
-
object RecentTabsHeader : AdapterItem(RecentTabsHeaderViewHolder.LAYOUT_ID)
object RecentTabItem : AdapterItem(RecentTabViewHolder.LAYOUT_ID)
@@ -293,11 +285,6 @@ class SessionControlAdapter(
viewLifecycleOwner = viewLifecycleOwner,
interactor = interactor,
)
- TorBootstrapPagerViewHolder.LAYOUT_ID -> TorBootstrapPagerViewHolder(
- view,
- components,
- interactor
- )
NoCollectionsMessageViewHolder.LAYOUT_ID ->
NoCollectionsMessageViewHolder(
view,
@@ -307,15 +294,6 @@ class SessionControlAdapter(
interactor,
)
BottomSpacerViewHolder.LAYOUT_ID -> BottomSpacerViewHolder(view)
-
- TorOnboardingSecurityLevelViewHolder.LAYOUT_ID -> TorOnboardingSecurityLevelViewHolder(
- view,
- interactor
- )
- TorOnboardingDonateViewHolder.LAYOUT_ID -> TorOnboardingDonateViewHolder(
- view,
- interactor
- )
else -> throw IllegalStateException()
}
}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
=====================================
@@ -134,21 +134,6 @@ interface SessionControlController {
*/
fun handleTopSiteLongClicked(topSite: TopSite)
- /**
- * @see [OnboardingInteractor.onOpenSettingsClicked]
- */
- fun handleOpenSettingsClicked()
-
- /**
- * @see [OnboardingInteractor.onOpenSecurityLevelSettingsClicked]
- */
- fun handleOpenSecurityLevelSettingsClicked()
-
- /**
- * @see [OnboardingInteractor.onDonateClicked]
- */
- fun handleDonateClicked()
-
/**
* @see [CollectionInteractor.onToggleCollectionExpanded]
*/
@@ -188,31 +173,6 @@ interface SessionControlController {
* @see [SessionControlInteractor.reportSessionMetrics]
*/
fun handleReportSessionMetrics(state: AppState)
-
- /**
- * @see [TorBootstrapInteractor.onTorBootstrapConnectClicked]
- */
- fun handleTorBootstrapConnectClicked()
-
- /**
- * @see [TorBootstrapInteractor.onTorStopBootstrapping]
- */
- fun handleTorStopBootstrapping()
-
- /**
- * @see [TorBootstrapInteractor.onTorStartBootstrapping]
- */
- fun handleTorStartBootstrapping()
-
- /**
- * @see [TorBootstrapInteractor.onTorStartDebugBootstrapping]
- */
- fun handleTorStartDebugBootstrapping()
-
- /**
- * @see [TorBootstrapInteractor.onTorBootstrapNetworkSettingsClicked]
- */
- fun handleTorNetworkSettingsClicked()
}
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
@@ -233,10 +193,6 @@ class DefaultSessionControlController(
private val registerCollectionStorageObserver: () -> Unit,
private val removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit,
private val showTabTray: () -> Unit,
- private val handleTorBootstrapConnect: () -> Unit,
- private val initiateTorBootstrap: (Boolean) -> Unit,
- private val cancelTorBootstrap: () -> Unit,
- private val openTorNetworkSettings: () -> Unit
) : SessionControlController {
override fun handleCollectionAddTabTapped(collection: TabCollection) {
@@ -511,25 +467,6 @@ class DefaultSessionControlController(
}
}
}
-
- override fun handleOpenSettingsClicked() {
- val directions = HomeFragmentDirections.actionGlobalPrivateBrowsingFragment()
- navController.nav(R.id.homeFragment, directions)
- }
-
- override fun handleOpenSecurityLevelSettingsClicked() {
- val directions = HomeFragmentDirections.actionGlobalTorSecurityLevelFragment()
- navController.nav(R.id.homeFragment, directions)
- }
-
- override fun handleDonateClicked() {
- activity.openToBrowserAndLoad(
- searchTermOrURL = SupportUtils.DONATE_URL,
- newTab = true,
- from = BrowserDirection.FromHome
- )
- }
-
override fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
appStore.dispatch(AppAction.CollectionExpanded(collection, expand))
}
@@ -601,24 +538,4 @@ class DefaultSessionControlController(
RecentBookmarks.recentBookmarksCount.set(state.recentBookmarks.size.toLong())
}
-
- override fun handleTorBootstrapConnectClicked() {
- handleTorBootstrapConnect()
- }
-
- override fun handleTorStopBootstrapping() {
- cancelTorBootstrap()
- }
-
- override fun handleTorStartBootstrapping() {
- initiateTorBootstrap(false)
- }
-
- override fun handleTorStartDebugBootstrapping() {
- initiateTorBootstrap(true)
- }
-
- override fun handleTorNetworkSettingsClicked() {
- openTorNetworkSettings()
- }
}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
=====================================
@@ -129,26 +129,6 @@ interface CollectionInteractor {
fun onRemoveCollectionsPlaceholder()
}
-/**
- * Interface for onboarding related actions in the [SessionControlInteractor].
- */
-interface OnboardingInteractor {
- /**
- * Hides the onboarding and navigates to Search. Called when a user clicks on the "Start Browsing" button.
- */
- fun onStartBrowsingClicked()
-
- /**
- * Hides the onboarding and navigates to Settings. Called when a user clicks on the "Open settings" button.
- */
- fun onOpenSettingsClicked()
-
- /**
- * Opens a custom tab to privacy notice url. Called when a user clicks on the "read our privacy notice" button.
- */
- fun onDonateClicked()
-}
-
interface CustomizeHomeIteractor {
/**
* Opens the customize home settings page.
@@ -156,34 +136,6 @@ interface CustomizeHomeIteractor {
fun openCustomizeHomePage()
}
-interface TorBootstrapInteractor {
- /**
- * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
- */
- fun onTorBootstrapConnectClicked()
-
- /**
- * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
- */
- fun onTorStartBootstrapping()
-
- /**
- * Stop Tor bootstrapping. Called when a user clicks on the "settings" cog/button.
- */
- fun onTorStopBootstrapping()
-
- /**
- * Initiates Tor bootstrapping with debug logging. Called when bootstrapping fails with
- * the control.txt file not existing.
- */
- fun onTorStartDebugBootstrapping()
-
- /**
- * Open Tor Network Settings preference screen
- */
- fun onTorBootstrapNetworkSettingsClicked()
-}
-
/**
* Interface for top site related actions in the [SessionControlInteractor].
*/
@@ -295,7 +247,6 @@ class SessionControlInteractor(
PocketStoriesInteractor,
PrivateBrowsingInteractor,
SearchSelectorInteractor,
- TorBootstrapInteractor,
WallpaperInteractor {
override fun onCollectionAddTabTapped(collection: TabCollection) {
@@ -358,15 +309,6 @@ class SessionControlInteractor(
return controller.handleShowWallpapersOnboardingDialog(state)
}
- // TODO: Do these still work, if not overrides, cus parent class dropped, are they wired in still?
- fun onOpenSettingsClicked() {
- controller.handleOpenSettingsClicked()
- }
-
- fun onDonateClicked() {
- controller.handleDonateClicked()
- }
-
override fun onToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
controller.handleToggleCollectionExpanded(collection, expand)
}
@@ -500,24 +442,4 @@ class SessionControlInteractor(
override fun onMenuItemTapped(item: SearchSelectorMenu.Item) {
searchSelectorController.handleMenuItemTapped(item)
}
-
- override fun onTorBootstrapConnectClicked() {
- controller.handleTorBootstrapConnectClicked()
- }
-
- override fun onTorStopBootstrapping() {
- controller.handleTorStopBootstrapping()
- }
-
- override fun onTorStartBootstrapping() {
- controller.handleTorStartBootstrapping()
- }
-
- override fun onTorStartDebugBootstrapping() {
- controller.handleTorStartDebugBootstrapping()
- }
-
- override fun onTorBootstrapNetworkSettingsClicked() {
- controller.handleTorNetworkSettingsClicked()
- }
}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
=====================================
@@ -126,15 +126,6 @@ private fun showCollections(
private fun privateModeAdapterItems() = listOf(AdapterItem.PrivateBrowsingDescription)
-private fun bootstrapAdapterItems() = listOf(AdapterItem.TorBootstrap)
-
-private fun torOnboardingAdapterItems() =
- listOf(
- AdapterItem.TorOnboardingSecurityLevel,
- AdapterItem.TorOnboardingDonate,
- // AdapterItem.OnboardingFinish
- )
-
private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when (mode) {
is Mode.Normal -> normalModeAdapterItems(
settings,
@@ -151,7 +142,6 @@ private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when
firstFrameDrawn,
)
is Mode.Private -> privateModeAdapterItems()
- is Mode.Bootstrap -> bootstrapAdapterItems()
}
private fun collectionTabItems(collection: TabCollection) =
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingDonateViewHolder.kt deleted
=====================================
@@ -1,28 +0,0 @@
-/* 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.home.sessioncontrol.viewholders.onboarding
-
-import android.view.View
-import androidx.recyclerview.widget.RecyclerView
-import org.mozilla.fenix.R
-import org.mozilla.fenix.databinding.TorOnboardingDonateBinding
-import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
-
-class TorOnboardingDonateViewHolder(
- view: View,
- private val interactor: SessionControlInteractor
-) : RecyclerView.ViewHolder(view) {
-
- init {
- val binding = TorOnboardingDonateBinding.bind(view)
- binding.donateNowButton.setOnClickListener {
- interactor.onDonateClicked()
- }
- }
-
- companion object {
- const val LAYOUT_ID = R.layout.tor_onboarding_donate
- }
-}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt deleted
=====================================
@@ -1,95 +0,0 @@
-/* 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.home.sessioncontrol.viewholders.onboarding
-
-import android.view.View
-import androidx.recyclerview.widget.RecyclerView
-import org.mozilla.fenix.R
-import org.mozilla.fenix.databinding.TorOnboardingSecurityLevelBinding
-import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
-import org.mozilla.fenix.ext.components
-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(
- view: View,
- private val interactor: SessionControlInteractor
-) : RecyclerView.ViewHolder(view) {
-
- private var _binding: TorOnboardingSecurityLevelBinding? = null
- private val binding get() = _binding!!
-
- private var standardSecurityLevel: OnboardingRadioButton
- private var saferSecurityLevel: OnboardingRadioButton
- private var safestSecurityLevel: OnboardingRadioButton
-
- init {
- _binding = TorOnboardingSecurityLevelBinding.bind(view)
- binding.headerText.setOnboardingIcon(R.drawable.ic_onboarding_tracking_protection)
-
- standardSecurityLevel = binding.securityLevelStandardOption
- saferSecurityLevel = binding.securityLevelSaferOption
- safestSecurityLevel = binding.securityLevelSafestOption
-
- binding.descriptionText.text = view.context.getString(
- R.string.tor_onboarding_security_level_description
- )
-
- setupRadioGroup(view)
-
- }
-
- private fun setupRadioGroup(view: View) {
-
- addToRadioGroup(standardSecurityLevel, saferSecurityLevel, safestSecurityLevel)
-
- 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(SecurityLevel.STANDARD, view)
- }
-
- saferSecurityLevel.onClickListener {
- updateSecurityLevel(SecurityLevel.SAFER, view)
- }
-
- safestSecurityLevel.onClickListener {
- updateSecurityLevel(SecurityLevel.SAFEST, view)
- }
-
- updateSecurityLevel(securityLevel, view)
- }
-
- private fun updateSecurityLevel(newLevel: SecurityLevel, view: View) {
- val resources = view.context.resources
- val securityLevel = when (newLevel) {
- SecurityLevel.STANDARD -> resources.getString(R.string.tor_security_level_standard_option)
- SecurityLevel.SAFER -> resources.getString(R.string.tor_security_level_safer_option)
- SecurityLevel.SAFEST -> resources.getString(R.string.tor_security_level_safest_option)
- }
- binding.currentLevel.text = resources.getString(
- R.string.tor_onboarding_chosen_security_level_label, securityLevel
- )
- view.context.components.let {
- it.core.engine.settings.torSecurityLevel = newLevel.intRepresentation
- }
- }
-
- companion object {
- const val LAYOUT_ID = R.layout.tor_onboarding_security_level
- }
-}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt
=====================================
@@ -0,0 +1,195 @@
+/* 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.annotation.VisibleForTesting
+import androidx.core.view.children
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.lifecycleScope
+import org.mozilla.fenix.BuildConfig
+import org.mozilla.fenix.databinding.FragmentHomeBinding
+import org.mozilla.fenix.ext.requireComponents
+import org.mozilla.fenix.tor.bootstrap.TorQuickStart
+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.ext.components
+import org.mozilla.fenix.ext.hideToolbar
+import org.mozilla.fenix.tor.controller.DefaultTorBootstrapController
+import org.mozilla.fenix.tor.view.TorBootstrapView
+
+
+@Suppress("TooManyFunctions", "LargeClass")
+class TorBootstrapFragment : Fragment() {
+ private val torQuickStart by lazy { TorQuickStart(requireContext()) }
+
+ internal var _binding: FragmentHomeBinding? = null
+ private val binding get() = _binding!!
+
+
+ private var torBootstrapView: TorBootstrapView? = null
+
+ private var _torBootstrapInteractor: TorBootstrapInteractor? = null
+ private val torBootstrapInteractor: TorBootstrapInteractor
+ get() = _torBootstrapInteractor!!
+
+ private lateinit var torBootstrapStatus: TorBootstrapStatus
+
+
+ @Suppress("LongMethod")
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View {
+ _binding = FragmentHomeBinding.inflate(inflater, container, false)
+ val components = requireComponents
+
+ torBootstrapStatus = TorBootstrapStatus(
+ torQuickStart,
+ !BuildConfig.DISABLE_TOR,
+ components.torController,
+ ::dispatchModeChanges
+ )
+
+ if (!torBootstrapStatus.isBootstrapping()) {
+ openHome()
+ }
+
+ // Was _sessionControlInteractor
+ _torBootstrapInteractor = DefaultTorBootstrapInteractor(
+ controller = DefaultTorBootstrapController(
+ handleTorBootstrapConnect = ::handleTorBootstrapConnect,
+ cancelTorBootstrap = ::cancelTorBootstrap,
+ initiateTorBootstrap = ::initiateTorBootstrap,
+ openTorNetworkSettings = ::openTorNetworkSettings
+ ),
+ )
+
+ torBootstrapView = TorBootstrapView(
+ containerView = binding.sessionControlRecyclerView,
+ viewLifecycleOwner = viewLifecycleOwner,
+ interactor = torBootstrapInteractor,
+ )
+
+ adjustHomeFragmentView()
+ updateSessionControlView()
+ showSessionControlView()
+
+ return binding.root
+ }
+
+ private fun updateSessionControlView() {
+ torBootstrapView?.update(requireContext().components.appStore.state)
+ }
+
+ // This function should be paired with showSessionControlView()
+ private fun adjustHomeFragmentView() {
+ binding.sessionControlRecyclerView.apply {
+ visibility = View.INVISIBLE
+ }
+
+ binding.sessionControlRecyclerView.apply {
+ setPadding(0, 0, 0, 0)
+ (layoutParams as ViewGroup.MarginLayoutParams).setMargins(0, 0, 0, 0)
+ }
+
+ binding.homeAppBar.apply {
+ visibility = View.GONE
+
+ // Reset this as SCROLL in case it was previously set as NO_SCROLL after bootstrap
+ children.forEach {
+ (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
+ AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
+ }
+ }
+ binding.onionPatternImage.apply {
+ visibility = View.GONE
+ }
+ binding.toolbarLayout.apply {
+ visibility = View.GONE
+ }
+ }
+
+ // This function should be paired with adjustHomeFragmentView()
+ private fun showSessionControlView() {
+ binding.sessionControlRecyclerView.apply {
+ visibility = View.VISIBLE
+ }
+ }
+
+ private fun dispatchModeChanges(isBootstrapping: Boolean) {
+ //requireComponents.appStore.dispatch(AppAction.ModeChange(mode))
+ if (!isBootstrapping) {
+ openHome()
+ } else {
+ adjustHomeFragmentView()
+ updateSessionControlView()
+ showSessionControlView()
+ }
+ }
+
+ override fun onStop() {
+ super.onStop()
+ torBootstrapStatus.unregisterTorListener()
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ torBootstrapStatus.registerTorListener()
+
+ // fenix#40176: Ensure the Home fragment is rendered correctly when we resume.
+ val isBootstraping = torBootstrapStatus.isBootstrapping()
+
+ if (!isBootstraping) {
+ openHome()
+ }
+
+ adjustHomeFragmentView()
+ updateSessionControlView()
+ showSessionControlView()
+
+ hideToolbar()
+
+ // Whenever a tab is selected its last access timestamp is automatically updated by A-C.
+ // However, in the case of resuming the app to the home fragment, we already have an
+ // existing selected tab, but its last access timestamp is outdated. No action is
+ // triggered to cause an automatic update on warm start (no tab selection occurs). So we
+ // update it manually here.
+ requireComponents.useCases.sessionUseCases.updateLastAccess()
+ }
+
+ private fun handleTorBootstrapConnect() {
+ requireComponents.torController.onTorConnecting()
+ }
+
+ private fun cancelTorBootstrap() {
+ requireComponents.torController.stopTor()
+ }
+
+ private fun initiateTorBootstrap(withDebugLogging: Boolean = false) {
+ requireComponents.torController.initiateTorBootstrap(lifecycleScope, withDebugLogging)
+ }
+
+ private fun openTorNetworkSettings() {
+ val directions =
+ TorBootstrapFragmentDirections.actionTorbootstrapFragmentToTorNetworkSettingsFragment()
+ findNavController().navigate(directions)
+ }
+
+ private fun openHome() {
+ val directions =
+ TorBootstrapFragmentDirections
+ .actionStartupHome()
+ findNavController().navigate(directions)
+ }
+
+}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt
=====================================
@@ -0,0 +1,48 @@
+/* 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 org.mozilla.fenix.tor.bootstrap.TorQuickStart
+
+@SuppressWarnings("LongParameterList", "TooManyFunctions")
+class TorBootstrapStatus(
+ private val torQuickStart: TorQuickStart,
+ private val shouldStartTor: Boolean,
+ private val torController: TorController,
+ private val dispatchModeChanges: (isShouldBootstrap: Boolean) -> Unit
+ ) : TorEvents {
+
+ init {
+ torController.registerTorListener(this)
+ }
+
+ fun isBootstrapping() = (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped))
+
+
+ @SuppressWarnings("EmptyFunctionBlock")
+ override fun onTorConnecting() {
+ }
+
+ override fun onTorConnected() {
+ dispatchModeChanges(isBootstrapping())
+ }
+
+ override fun onTorStopped() {
+ dispatchModeChanges(isBootstrapping())
+ }
+
+ @SuppressWarnings("EmptyFunctionBlock")
+ override fun onTorStatusUpdate(entry: String?, status: String?) {
+ }
+
+ fun unregisterTorListener() {
+ torController.unregisterTorListener(this)
+ }
+
+ fun registerTorListener() {
+ torController.registerTorListener(this)
+ }
+
+}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/controller/TorBootstrapController.kt
=====================================
@@ -0,0 +1,63 @@
+/* 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.controller
+
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
+
+interface TorBootstrapController {
+ /**
+ * @see [TorBootstrapInteractor.onTorBootstrapConnectClicked]
+ */
+ fun handleTorBootstrapConnectClicked()
+
+ /**
+ * @see [TorBootstrapInteractor.onTorStopBootstrapping]
+ */
+ fun handleTorStopBootstrapping()
+
+ /**
+ * @see [TorBootstrapInteractor.onTorStartBootstrapping]
+ */
+ fun handleTorStartBootstrapping()
+
+ /**
+ * @see [TorBootstrapInteractor.onTorStartDebugBootstrapping]
+ */
+ fun handleTorStartDebugBootstrapping()
+
+ /**
+ * @see [TorBootstrapInteractor.onTorBootstrapNetworkSettingsClicked]
+ */
+ fun handleTorNetworkSettingsClicked()
+
+
+}
+
+class DefaultTorBootstrapController(
+ private val handleTorBootstrapConnect: () -> Unit,
+ private val initiateTorBootstrap: (Boolean) -> Unit,
+ private val cancelTorBootstrap: () -> Unit,
+ private val openTorNetworkSettings: () -> Unit
+) : TorBootstrapController {
+ override fun handleTorBootstrapConnectClicked() {
+ handleTorBootstrapConnect()
+ }
+
+ override fun handleTorStopBootstrapping() {
+ cancelTorBootstrap()
+ }
+
+ override fun handleTorStartBootstrapping() {
+ initiateTorBootstrap(false)
+ }
+
+ override fun handleTorStartDebugBootstrapping() {
+ initiateTorBootstrap(true)
+ }
+
+ override fun handleTorNetworkSettingsClicked() {
+ openTorNetworkSettings()
+ }
+}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/interactor/TorBootstrapInteractor.kt
=====================================
@@ -0,0 +1,60 @@
+/* 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.interactor
+
+import org.mozilla.fenix.tor.controller.TorBootstrapController
+
+interface TorBootstrapInteractor {
+ /**
+ * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
+ */
+ fun onTorBootstrapConnectClicked()
+
+ /**
+ * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
+ */
+ fun onTorStartBootstrapping()
+
+ /**
+ * Stop Tor bootstrapping. Called when a user clicks on the "settings" cog/button.
+ */
+ fun onTorStopBootstrapping()
+
+ /**
+ * Initiates Tor bootstrapping with debug logging. Called when bootstrapping fails with
+ * the control.txt file not existing.
+ */
+ fun onTorStartDebugBootstrapping()
+
+ /**
+ * Open Tor Network Settings preference screen
+ */
+ fun onTorBootstrapNetworkSettingsClicked()
+}
+
+class DefaultTorBootstrapInteractor(
+ private val controller: TorBootstrapController,
+) : TorBootstrapInteractor {
+
+ override fun onTorBootstrapConnectClicked() {
+ controller.handleTorBootstrapConnectClicked()
+ }
+
+ override fun onTorStopBootstrapping() {
+ controller.handleTorStopBootstrapping()
+ }
+
+ override fun onTorStartBootstrapping() {
+ controller.handleTorStartBootstrapping()
+ }
+
+ override fun onTorStartDebugBootstrapping() {
+ controller.handleTorStartDebugBootstrapping()
+ }
+
+ override fun onTorBootstrapNetworkSettingsClicked() {
+ controller.handleTorNetworkSettingsClicked()
+ }
+}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapAdapter.kt
=====================================
@@ -0,0 +1,83 @@
+/* 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.view
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.annotation.LayoutRes
+import androidx.lifecycle.LifecycleOwner
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.mozilla.fenix.components.Components
+import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
+
+sealed class AdapterItem(@LayoutRes val viewType: Int) {
+ object TorBootstrap : AdapterItem(TorBootstrapPagerViewHolder.LAYOUT_ID)
+
+
+ open fun sameAs(other: AdapterItem) = this::class == other::class
+ open fun getChangePayload(newItem: AdapterItem): Any? = null
+ open fun contentsSameAs(other: AdapterItem) = this::class == other::class
+
+}
+
+class AdapterItemDiffCallback : DiffUtil.ItemCallback<AdapterItem>() {
+ override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
+ oldItem.sameAs(newItem)
+
+ @Suppress("DiffUtilEquals")
+ override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
+ oldItem.contentsSameAs(newItem)
+
+ override fun getChangePayload(oldItem: AdapterItem, newItem: AdapterItem): Any? {
+ return oldItem.getChangePayload(newItem) ?: return super.getChangePayload(oldItem, newItem)
+ }
+}
+
+
+
+class TorBootstrapAdapter(
+ private val interactor: TorBootstrapInteractor,
+ private val viewLifecycleOwner: LifecycleOwner,
+ private val components: Components,
+) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) {
+
+ // This method triggers the ComplexMethod lint error when in fact it's quite simple.
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
+ return when (viewType) {
+ TorBootstrapPagerViewHolder.LAYOUT_ID -> TorBootstrapPagerViewHolder(
+ view,
+ components,
+ interactor
+ )
+ else -> throw IllegalStateException()
+ }
+ }
+
+ override fun getItemViewType(position: Int) = getItem(position).viewType
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) {
+ if (payloads.isEmpty()) {
+ onBindViewHolder(holder, position)
+ } else {
+ when (holder) {
+ is TopSitePagerViewHolder -> {
+ if (payloads[0] is org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload) {
+ val payload = payloads[0] as org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload
+ holder.update(payload)
+ }
+ }
+ }
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ // no-op. This ViewHolder receives the HomeStore as argument and will observe that
+ // without the need for us to manually update from here the data to be displayed.
+ }
+}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapConnectViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt
=====================================
@@ -2,17 +2,16 @@
* 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.home.sessioncontrol.viewholders
+package org.mozilla.fenix.tor.view
import android.view.View
-import androidx.appcompat.widget.SwitchCompat
import androidx.recyclerview.widget.RecyclerView
import org.mozilla.fenix.R
+import org.mozilla.fenix.components.Components
import org.mozilla.fenix.databinding.TorBootstrapConnectBinding
import org.mozilla.fenix.tor.TorEvents
import org.mozilla.fenix.tor.bootstrap.TorQuickStart
-import org.mozilla.fenix.components.Components
-import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
class TorBootstrapConnectViewHolder(
private val view: View,
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapLoggerViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapLoggerViewHolder.kt
=====================================
@@ -2,20 +2,20 @@
* 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.home.sessioncontrol.viewholders
+package org.mozilla.fenix.tor.view
import android.text.method.ScrollingMovementMethod
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import org.mozilla.fenix.R
+import org.mozilla.fenix.components.Components
import org.mozilla.fenix.databinding.TorBootstrapLoggerBinding
import org.mozilla.fenix.tor.TorEvents
-import org.mozilla.fenix.components.Components
class TorBootstrapLoggerViewHolder(
- private val view: View,
- private val components: Components
-) : RecyclerView.ViewHolder(view), TorEvents {
+ private val view: View,
+ private val components: Components
+ ) : RecyclerView.ViewHolder(view), TorEvents {
private var entries = mutableListOf<String>()
private var binding: TorBootstrapLoggerBinding
@@ -25,10 +25,10 @@ class TorBootstrapLoggerViewHolder(
components.torController.registerTorListener(this)
val currentEntries = components.torController.logEntries
- .filter { it.first != null }
- .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
- // Keep synchronized with format in onTorStatusUpdate
- .flatMap { listOf("(${it.second}) '${it.first}'") }
+ .filter { it.first != null }
+ .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
+ // Keep synchronized with format in onTorStatusUpdate
+ .flatMap { listOf("(${it.second}) '${it.first}'") }
val entriesLen = currentEntries.size
val subListOffset = if (entriesLen > MAX_NEW_ENTRIES) MAX_NEW_ENTRIES else entriesLen
entries = currentEntries.subList((entriesLen - subListOffset), entriesLen) as MutableList<String>
@@ -72,4 +72,5 @@ class TorBootstrapLoggerViewHolder(
const val MAX_NEW_ENTRIES = 24
const val MAX_LINES = 25
}
+
}
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/torbootstrap/BootstrapPagerAdapter.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerAdapter.kt
=====================================
@@ -2,18 +2,15 @@
* 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.home.sessioncontrol.viewholders.torbootstrap
+package org.mozilla.fenix.tor.view
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
import org.mozilla.fenix.components.Components
-import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
-import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapConnectViewHolder
-import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapLoggerViewHolder
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
-class BootstrapPagerAdapter(
+class TorBootstrapPagerAdapter(
private val components: Components,
private val interactor: TorBootstrapInteractor
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
=====================================
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapPagerViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerViewHolder.kt
=====================================
@@ -2,23 +2,22 @@
* 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.home.sessioncontrol.viewholders
+package org.mozilla.fenix.tor.view
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import org.mozilla.fenix.R
-import org.mozilla.fenix.databinding.TorBootstrapPagerBinding
import org.mozilla.fenix.components.Components
-import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
-import org.mozilla.fenix.home.sessioncontrol.viewholders.torbootstrap.BootstrapPagerAdapter
+import org.mozilla.fenix.databinding.TorBootstrapPagerBinding
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
class TorBootstrapPagerViewHolder(
- view: View,
- components: Components,
- interactor: TorBootstrapInteractor
-) : RecyclerView.ViewHolder(view) {
+ view: View,
+ components: Components,
+ interactor: TorBootstrapInteractor
+ ) : RecyclerView.ViewHolder(view) {
- private val bootstrapPagerAdapter = BootstrapPagerAdapter(components, interactor)
+ private val bootstrapPagerAdapter = TorBootstrapPagerAdapter(components, interactor)
init {
val binding = TorBootstrapPagerBinding.bind(view)
=====================================
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapView.kt
=====================================
@@ -0,0 +1,49 @@
+/* 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.view
+
+import androidx.lifecycle.LifecycleOwner
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import org.mozilla.fenix.components.appstate.AppState
+import org.mozilla.fenix.ext.components
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
+
+
+class TorBootstrapView(
+ containerView: RecyclerView,
+ viewLifecycleOwner: LifecycleOwner,
+ interactor: TorBootstrapInteractor,
+) {
+
+ val view: RecyclerView = containerView //as RecyclerView
+
+ private fun bootstrapAdapterItems() = listOf(AdapterItem.TorBootstrap)
+
+ private val torBootstrapAdapter = TorBootstrapAdapter(
+ interactor,
+ viewLifecycleOwner,
+ containerView.context.components,
+ )
+
+ //private val torBootstrapAdapter =
+ // TorBootstrapAdapter(interactor, containerView.context.components)
+ //private val torBootstrapAdapter = TorBootstrapPagerAdapter(containerView.context.components, interactor)
+
+ init {
+ containerView.apply {
+ adapter = torBootstrapAdapter
+ layoutManager = LinearLayoutManager(containerView.context)
+ }
+ }
+
+ private fun AppState.toAdapterList(): List<AdapterItem> {
+ return bootstrapAdapterItems()
+ }
+
+ fun update(state: AppState) {
+ torBootstrapAdapter.submitList(state.toAdapterList())
+ }
+}
=====================================
fenix/app/src/main/res/drawable/tor_onboarding_donate_gradient.xml deleted
=====================================
@@ -1,15 +0,0 @@
-<?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/. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape>
- <gradient
- android:angle="45"
- android:startColor="#07d1db"
- android:endColor="#b240f5"
- android:type="linear" />
- </shape>
- </item>
-</selector>
=====================================
fenix/app/src/main/res/drawable/tor_onboarding_donate_rounded_corners.xml deleted
=====================================
@@ -1,11 +0,0 @@
-<?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/. -->
-
-<!-- Used for rounding the corners of a button -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="#70efde" />
- <corners android:radius="10dp" />
-</shape>
=====================================
fenix/app/src/main/res/layout/tor_onboarding_donate.xml deleted
=====================================
@@ -1,46 +0,0 @@
-<?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"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/onboarding_card"
- style="@style/TorOnboardingDonateCardLightWithPadding"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView
- android:id="@+id/header_text"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:text="@string/tor_onboarding_donate_header"
- android:textAppearance="@style/TorHeaderTextStyle"
- android:gravity="center_vertical"
- android:lines="1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
- <TextView
- android:id="@+id/description_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TorBody16TextStyle"
- android:layout_marginTop="14dp"
- android:text="@string/tor_onboarding_donate_description"
- app:layout_constraintTop_toBottomOf="@id/header_text"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
-
- <Button
- style="@style/TorDonateOnboardingButton"
- android:id="@+id/donate_now_button"
- android:text="@string/tor_onboarding_donate_button"
- android:layout_marginTop="10dp"
- android:textAppearance="@style/TorHeaderTextStyle"
- android:background="@drawable/tor_onboarding_donate_rounded_corners"
- app:layout_constraintTop_toBottomOf="@id/description_text"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
=====================================
fenix/app/src/main/res/layout/tor_onboarding_security_level.xml deleted
=====================================
@@ -1,123 +0,0 @@
-<?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"
- xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/onboarding_card"
- style="@style/OnboardingCardLightWithPadding"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false">
-
- <TextView
- android:id="@+id/header_text"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:drawablePadding="12dp"
- android:gravity="center_vertical"
- android:lines="1"
- android:text="@string/tor_onboarding_security_level"
- android:textAppearance="@style/HeaderTextStyle"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- tools:drawableStart="@drawable/ic_onboarding_tracking_protection" />
-
- <TextView
- android:id="@+id/description_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- android:textAppearance="@style/Body14TextStyle"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/current_level"
- tools:text="@string/tor_onboarding_security_level_description" />
-
- <TextView
- android:id="@+id/current_level"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="12dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/header_text"
- tools:text="@string/tor_onboarding_chosen_security_level_label" />
-
- <org.mozilla.fenix.onboarding.OnboardingRadioButton
- android:id="@+id/security_level_standard_option"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp"
- android:background="@android:color/transparent"
- android:checked="true"
- android:foreground="@drawable/rounded_ripple"
- android:gravity="top"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- 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_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
- android:id="@+id/security_level_safer_option"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp"
- android:background="@android:color/transparent"
- android:checked="false"
- android:foreground="@drawable/rounded_ripple"
- android:gravity="top"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- 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_option"
- app:onboardingKey="@string/pref_key_tor_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
- android:id="@+id/security_level_safest_option"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp"
- android:background="@android:color/transparent"
- android:checked="false"
- android:foreground="@drawable/rounded_ripple"
- android:gravity="top"
- android:paddingStart="8dp"
- android:paddingEnd="8dp"
- 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_safer_option"
- app:onboardingKey="@string/pref_key_tor_security_level_safest_option"
- app:onboardingKeyDescription="@string/tor_security_level_safest_description"
- app:onboardingKeyTitle="@string/tor_security_level_safest_option"
- tools:text="Safest" />
-
- <Button
- android:id="@+id/open_settings_button"
- style="@style/NeutralOnboardingButton"
- android:layout_marginTop="16dp"
- android:text="@string/tor_onboarding_security_settings_button"
- app:layout_constraintTop_toBottomOf="@id/security_level_safest_option"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
=====================================
fenix/app/src/main/res/navigation/nav_graph.xml
=====================================
@@ -21,6 +21,12 @@
app:popUpTo="@id/startupFragment"
app:popUpToInclusive="true" />
+ <action
+ android:id="@+id/action_startup_torbootstrap"
+ app:destination="@id/torbootstrapFragment"
+ app:popUpTo="@id/startupFragment"
+ app:popUpToInclusive="true" />
+
<action
android:id="@+id/action_global_home"
app:destination="@id/homeFragment"
@@ -247,6 +253,24 @@
app:popUpToInclusive="true" />
</fragment>
+ <fragment
+ android:id="@+id/torbootstrapFragment"
+ android:name="org.mozilla.fenix.tor.TorBootstrapFragment"
+ tools:layout="@layout/fragment_home">
+ <action
+ android:id="@+id/action_home"
+ app:destination="@id/homeFragment"
+ app:popUpTo="@id/torbootstrapFragment"
+ app:popUpToInclusive="true" />
+ <action
+ android:id="@+id/action_torbootstrapFragment_to_torNetworkSettingsFragment"
+ app:destination="@id/torNetworkSettingsFragment"
+ 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>
+
<dialog
android:id="@+id/homeOnboardingDialogFragment"
android:name="org.mozilla.fenix.onboarding.HomeOnboardingDialogFragment" />
=====================================
fenix/app/src/main/res/values/styles.xml
=====================================
@@ -375,13 +375,6 @@
<item name="android:textColor">?attr/textPrimary</item>
</style>
- <!-- Ideally we should consolidate this with NeutralButton in the future -->
- <style name="TorDonateOnboardingButton" parent="NeutralButton">
- <item name="android:background">@drawable/tor_onboarding_donate_rounded_corners</item>
- <item name="backgroundTint">#70efde</item>
- <item name="android:textColor">#000000</item>
- </style>
-
<style name="DestructiveButton" parent="NeutralButton">
<item name="iconTint">@color/fx_mobile_icon_color_warning_button</item>
<item name="android:textColor">@color/fx_mobile_text_color_warning_button</item>
@@ -582,10 +575,6 @@
<item name="android:elevation">0dp</item>
</style>
- <style name="TorOnboardingDonateCardLightWithPadding" parent="OnboardingCardDark">
- <item name="android:background">@drawable/tor_onboarding_donate_gradient</item>
- </style>
-
<style name="SearchClipboardStyle">
<item name="android:ellipsize">end</item>
<item name="android:maxLines">1</item>
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/d1…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/d1…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][tor-browser-115.2.0esr-13.0-1] Bug 42072: 2023 year end campaign for about:tor.
by Pier Angelo Vendrame (@pierov) 12 Sep '23
by Pier Angelo Vendrame (@pierov) 12 Sep '23
12 Sep '23
Pier Angelo Vendrame pushed to branch tor-browser-115.2.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
51bcca21 by Henry Wilkes at 2023-09-12T15:25:12+01:00
Bug 42072: 2023 year end campaign for about:tor.
- - - - -
1 changed file:
- browser/locales/en-US/browser/tor-browser.ftl
Changes:
=====================================
browser/locales/en-US/browser/tor-browser.ftl
=====================================
@@ -39,3 +39,21 @@ tor-browser-home-message-testing = This is an unstable version of Tor Browser fo
# Shown in Home settings, corresponds to the default about:tor home page.
home-mode-choice-tor =
.label = Tor Browser Home
+
+
+## 2023 year-end-campaign.
+
+# Large introduction text.
+yec-2023-introduction = Right now, Tor Browser is protecting your privacy and the privacy of millions of people like you!
+# Follows directly below yec-2023-introduction.
+# The <span data-l10n-name="attention"> tag is meant to bring some styling attention to the first phrase, but doesn't have any semantic meaning.
+yec-2023-please-donate = <span data-l10n-name="attention">This is possible because of donations from our community.</span> If you value the privacy that Tor Browser offers yourself and others, please make a donation today. You’ll ensure Tor Browser continues to provide online privacy to everyone who needs it.
+# Shown only during a period where donations will be matched. The end date should match the end of the year.
+# $amount (Number) - The donation limit. This will be a whole-number and will be automatically formatted according to the language/locale: using the language's numeral symbols and thousand-separators.
+# NOTE: The amount should be shown as USD (United States dollar) currency. In the original English string, the first "$" is the literal USD currency symbol, and this can be changed or removed when translating to whatever is most appropriate for USD currency in the locale. In contrast, the "$" at the start of "$amount" is part of the Fluent format's syntax and should not be changed when translating.
+# For example, "${ $amount }" for English would eventually be shown as "$5,000", whilst "{ $amount } US$" for Arabic would be shown as "٥٬٠٠٠ US$".
+# Translators: If you need any help or clarification, feel free to ask a question on weblate or in IRC (#tor-l10n).
+yec-2023-matched-donation = From now until December 31, your gift will be matched one-to-one, up to ${ $amount }!
+yec-2023-close-button =
+ .title = Close
+yec-2023-donate-button = Donate now
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/51bcca2…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/51bcca2…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][base-browser-115.2.0esr-13.0-1] 2 commits: Revert "Bug 42022: Prevent extension search engines from breaking the whole search system"
by Pier Angelo Vendrame (@pierov) 12 Sep '23
by Pier Angelo Vendrame (@pierov) 12 Sep '23
12 Sep '23
Pier Angelo Vendrame pushed to branch base-browser-115.2.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
a4d48a95 by Pier Angelo Vendrame at 2023-09-12T15:02:03+02:00
Revert "Bug 42022: Prevent extension search engines from breaking the whole search system"
This reverts commit 9d7a9a7969394bc9503cc22ad9324666ca72cecc.
- - - - -
92026016 by Pier Angelo Vendrame at 2023-09-12T15:02:04+02:00
Bug 1849129: Prevent exceptions caused by extensions from interrupting the SearchService initialization. r=search-reviewers,Standard8
Differential Revision: https://phabricator.services.mozilla.com/D186456
- - - - -
3 changed files:
- toolkit/components/search/SearchService.sys.mjs
- + toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js
- toolkit/components/search/tests/xpcshell/xpcshell.ini
Changes:
=====================================
toolkit/components/search/SearchService.sys.mjs
=====================================
@@ -1574,11 +1574,18 @@ export class SearchService {
"engines reported by AddonManager startup"
);
for (let extension of this.#startupExtensions) {
- await this.#installExtensionEngine(
- extension,
- [lazy.SearchUtils.DEFAULT_TAG],
- true
- );
+ try {
+ await this.#installExtensionEngine(
+ extension,
+ [lazy.SearchUtils.DEFAULT_TAG],
+ true
+ );
+ } catch (ex) {
+ lazy.logConsole.error(
+ `#installExtensionEngine failed for ${extension.id}`,
+ ex
+ );
+ }
}
this.#startupExtensions.clear();
@@ -2715,7 +2722,6 @@ export class SearchService {
};
let engines = [];
- let revert = false;
for (let locale of locales) {
lazy.logConsole.debug(
"addEnginesFromExtension: installing:",
@@ -2723,28 +2729,7 @@ export class SearchService {
":",
locale
);
- try {
- engines.push(await installLocale(locale));
- } catch (err) {
- lazy.logConsole.error(
- `Could not install the search engine of ${extension.id}`,
- err
- );
- revert = true;
- break;
- }
- }
- if (revert) {
- for (let engine of engines) {
- try {
- this.removeEngine(engine);
- } catch (err) {
- lazy.logConsole.warn(
- "Failed to revert the addition of a search engine",
- err
- );
- }
- }
+ engines.push(await installLocale(locale));
}
return engines;
}
=====================================
toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js
=====================================
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const lazy = {};
+
+const { promiseShutdownManager, promiseStartupManager } = AddonTestUtils;
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ ExtensionTestUtils:
+ "resource://testing-common/ExtensionXPCShellUtils.sys.mjs",
+});
+
+add_setup(async function () {
+ let server = useHttpServer();
+ server.registerContentType("sjs", "sjs");
+ await SearchTestUtils.useTestEngines("test-extensions");
+ await promiseStartupManager();
+
+ registerCleanupFunction(async () => {
+ await promiseShutdownManager();
+ });
+});
+
+add_task(async function test_install_duplicate_engine_startup() {
+ let name = "Plain";
+ let id = "plain(a)tests.mozilla.org";
+ consoleAllowList.push(
+ `#installExtensionEngine failed for ${id}`,
+ `An engine called ${name} already exists`
+ );
+ // Do not use SearchTestUtils.installSearchExtension, as we need to manually
+ // start the search service after installing the extension.
+ let extensionInfo = {
+ useAddonManager: "permanent",
+ files: {},
+ manifest: SearchTestUtils.createEngineManifest({
+ name,
+ search_url: "https://example.com/plain",
+ }),
+ };
+
+ let extension = lazy.ExtensionTestUtils.loadExtension(extensionInfo);
+ await extension.startup();
+
+ await Services.search.init();
+
+ await AddonTestUtils.waitForSearchProviderStartup(extension);
+ let engine = await Services.search.getEngineByName(name);
+ let submission = engine.getSubmission("foo");
+ Assert.equal(
+ submission.uri.spec,
+ "https://duckduckgo.com/?q=foo&t=ffsb",
+ "Should have not changed the app provided engine."
+ );
+
+ await extension.unload();
+});
=====================================
toolkit/components/search/tests/xpcshell/xpcshell.ini
=====================================
@@ -191,6 +191,7 @@ support-files = data/search_ignorelist.json
[test_webextensions_migrate_to.js]
support-files = data/search-migration.json
[test_webextensions_normandy_upgrade.js]
+[test_webextensions_startup_duplicate.js]
[test_webextensions_startup_remove.js]
[test_webextensions_upgrade.js]
[test_webextensions_valid.js]
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/44ffc8…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/44ffc8…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][tor-browser-115.2.0esr-13.0-1] 2 commits: Revert "Bug 42022: Prevent extension search engines from breaking the whole search system"
by Pier Angelo Vendrame (@pierov) 12 Sep '23
by Pier Angelo Vendrame (@pierov) 12 Sep '23
12 Sep '23
Pier Angelo Vendrame pushed to branch tor-browser-115.2.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
967cf4de by Pier Angelo Vendrame at 2023-09-12T14:47:03+02:00
Revert "Bug 42022: Prevent extension search engines from breaking the whole search system"
This reverts commit 9d7a9a7969394bc9503cc22ad9324666ca72cecc.
- - - - -
27211730 by Pier Angelo Vendrame at 2023-09-12T14:48:04+02:00
Bug 1849129: Prevent exceptions caused by extensions from interrupting the SearchService initialization. r=search-reviewers,Standard8
Differential Revision: https://phabricator.services.mozilla.com/D186456
- - - - -
3 changed files:
- toolkit/components/search/SearchService.sys.mjs
- + toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js
- toolkit/components/search/tests/xpcshell/xpcshell.ini
Changes:
=====================================
toolkit/components/search/SearchService.sys.mjs
=====================================
@@ -1574,11 +1574,18 @@ export class SearchService {
"engines reported by AddonManager startup"
);
for (let extension of this.#startupExtensions) {
- await this.#installExtensionEngine(
- extension,
- [lazy.SearchUtils.DEFAULT_TAG],
- true
- );
+ try {
+ await this.#installExtensionEngine(
+ extension,
+ [lazy.SearchUtils.DEFAULT_TAG],
+ true
+ );
+ } catch (ex) {
+ lazy.logConsole.error(
+ `#installExtensionEngine failed for ${extension.id}`,
+ ex
+ );
+ }
}
this.#startupExtensions.clear();
@@ -2713,7 +2720,6 @@ export class SearchService {
};
let engines = [];
- let revert = false;
for (let locale of locales) {
lazy.logConsole.debug(
"addEnginesFromExtension: installing:",
@@ -2721,28 +2727,7 @@ export class SearchService {
":",
locale
);
- try {
- engines.push(await installLocale(locale));
- } catch (err) {
- lazy.logConsole.error(
- `Could not install the search engine of ${extension.id}`,
- err
- );
- revert = true;
- break;
- }
- }
- if (revert) {
- for (let engine of engines) {
- try {
- this.removeEngine(engine);
- } catch (err) {
- lazy.logConsole.warn(
- "Failed to revert the addition of a search engine",
- err
- );
- }
- }
+ engines.push(await installLocale(locale));
}
return engines;
}
=====================================
toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js
=====================================
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const lazy = {};
+
+const { promiseShutdownManager, promiseStartupManager } = AddonTestUtils;
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ ExtensionTestUtils:
+ "resource://testing-common/ExtensionXPCShellUtils.sys.mjs",
+});
+
+add_setup(async function () {
+ let server = useHttpServer();
+ server.registerContentType("sjs", "sjs");
+ await SearchTestUtils.useTestEngines("test-extensions");
+ await promiseStartupManager();
+
+ registerCleanupFunction(async () => {
+ await promiseShutdownManager();
+ });
+});
+
+add_task(async function test_install_duplicate_engine_startup() {
+ let name = "Plain";
+ let id = "plain(a)tests.mozilla.org";
+ consoleAllowList.push(
+ `#installExtensionEngine failed for ${id}`,
+ `An engine called ${name} already exists`
+ );
+ // Do not use SearchTestUtils.installSearchExtension, as we need to manually
+ // start the search service after installing the extension.
+ let extensionInfo = {
+ useAddonManager: "permanent",
+ files: {},
+ manifest: SearchTestUtils.createEngineManifest({
+ name,
+ search_url: "https://example.com/plain",
+ }),
+ };
+
+ let extension = lazy.ExtensionTestUtils.loadExtension(extensionInfo);
+ await extension.startup();
+
+ await Services.search.init();
+
+ await AddonTestUtils.waitForSearchProviderStartup(extension);
+ let engine = await Services.search.getEngineByName(name);
+ let submission = engine.getSubmission("foo");
+ Assert.equal(
+ submission.uri.spec,
+ "https://duckduckgo.com/?q=foo&t=ffsb",
+ "Should have not changed the app provided engine."
+ );
+
+ await extension.unload();
+});
=====================================
toolkit/components/search/tests/xpcshell/xpcshell.ini
=====================================
@@ -191,6 +191,7 @@ support-files = data/search_ignorelist.json
[test_webextensions_migrate_to.js]
support-files = data/search-migration.json
[test_webextensions_normandy_upgrade.js]
+[test_webextensions_startup_duplicate.js]
[test_webextensions_startup_remove.js]
[test_webextensions_upgrade.js]
[test_webextensions_valid.js]
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/8cff16…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/8cff16…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser] Pushed new tag FIREFOX_115_2_1esr_BUILD1
by Pier Angelo Vendrame (@pierov) 12 Sep '23
by Pier Angelo Vendrame (@pierov) 12 Sep '23
12 Sep '23
Pier Angelo Vendrame pushed new tag FIREFOX_115_2_1esr_BUILD1 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/FIREFOX_1…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser][base-browser-115.2.0esr-13.0-1] Bug 42084: Ensure English spoofing works even if preferences are set out of order.
by ma1 (@ma1) 12 Sep '23
by ma1 (@ma1) 12 Sep '23
12 Sep '23
ma1 pushed to branch base-browser-115.2.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
44ffc800 by hackademix at 2023-09-12T11:56:26+02:00
Bug 42084: Ensure English spoofing works even if preferences are set out of order.
- - - - -
1 changed file:
- toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
Changes:
=====================================
toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
=====================================
@@ -158,6 +158,9 @@ class _RFPHelper {
// Add RFP and Letterboxing observers if prefs are enabled
this._handleResistFingerprintingChanged();
this._handleLetterboxingPrefChanged();
+
+ // Synchronize language preferences if accidentally messed up (tor-browser#42084)
+ this._handleSpoofEnglishChanged();
}
uninit() {
@@ -211,6 +214,7 @@ class _RFPHelper {
this._handleResistFingerprintingChanged();
break;
case kPrefSpoofEnglish:
+ case "intl.accept_languages":
this._handleSpoofEnglishChanged();
break;
case kPrefLetterboxing:
@@ -259,6 +263,7 @@ class _RFPHelper {
}
_handleSpoofEnglishChanged() {
+ Services.prefs.removeObserver("intl.accept_languages", this);
switch (Services.prefs.getIntPref(kPrefSpoofEnglish)) {
case 0: // will prompt
// This should only happen when turning privacy.resistFingerprinting off.
@@ -277,6 +282,8 @@ class _RFPHelper {
case 2: // spoof
Services.prefs.setCharPref("intl.accept_languages", "en-US, en");
Services.prefs.setBoolPref("javascript.use_us_english_locale", true);
+ // Ensure spoofing works if preferences are set out of order
+ Services.prefs.addObserver("intl.accept_languages", this);
break;
default:
break;
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/44ffc80…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/44ffc80…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser] Pushed new tag base-browser-102.15.1esr-12.5-1-build1
by Pier Angelo Vendrame (@pierov) 12 Sep '23
by Pier Angelo Vendrame (@pierov) 12 Sep '23
12 Sep '23
Pier Angelo Vendrame pushed new tag base-browser-102.15.1esr-12.5-1-build1 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/base-brow…
You're receiving this email because of your account on gitlab.torproject.org.
1
0

[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-102.15.1esr-12.5-1-build1
by Pier Angelo Vendrame (@pierov) 12 Sep '23
by Pier Angelo Vendrame (@pierov) 12 Sep '23
12 Sep '23
Pier Angelo Vendrame pushed new tag tor-browser-102.15.1esr-12.5-1-build1 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows…
You're receiving this email because of your account on gitlab.torproject.org.
1
0