[tbb-commits] [Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.0-1] 3 commits: fixup! Add Tor integration and UI

Dan Ballard (@dan) git at gitlab.torproject.org
Tue Sep 12 15:53:33 UTC 2023



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 {
         }
     }
 }
-
- at 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
+
+
+ at 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
+
+ at 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/d19b676f148dade33eea6dd64cf54df7d4f52c3c...d2a7dfa603c2b5dec1607be715275e56dc3c04a2

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/d19b676f148dade33eea6dd64cf54df7d4f52c3c...d2a7dfa603c2b5dec1607be715275e56dc3c04a2
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20230912/7d1d2248/attachment-0001.htm>


More information about the tbb-commits mailing list