Dan Ballard pushed to branch firefox-android-115.2.1-13.0-1 at The Tor Project / Applications / firefox-android

Commits:

25 changed files:

Changes:

  • fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
    ... ... @@ -34,6 +34,7 @@ import androidx.annotation.VisibleForTesting.Companion.PROTECTED
    34 34
     import androidx.appcompat.app.ActionBar
    
    35 35
     import androidx.appcompat.widget.Toolbar
    
    36 36
     import androidx.core.app.NotificationManagerCompat
    
    37
    +import androidx.core.content.ContentProviderCompat.requireContext
    
    37 38
     import androidx.lifecycle.lifecycleScope
    
    38 39
     import androidx.navigation.NavDestination
    
    39 40
     import androidx.navigation.NavDirections
    
    ... ... @@ -285,6 +286,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
    285 286
                 it.start()
    
    286 287
             }
    
    287 288
     
    
    289
    +        /*
    
    288 290
             if (settings().shouldShowJunoOnboarding(
    
    289 291
                     hasUserBeenOnboarded = components.fenixOnboarding.userHasBeenOnboarded(),
    
    290 292
                     isLauncherIntent = intent.toSafeIntent().isLauncherIntent,
    
    ... ... @@ -295,6 +297,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
    295 297
                     navHost.navController.navigate(NavGraphDirections.actionGlobalJunoOnboarding())
    
    296 298
                 }
    
    297 299
             } else {
    
    300
    +         */
    
    298 301
                 lifecycleScope.launch(IO) {
    
    299 302
                     // showFullscreenMessageIfNeeded(applicationContext)
    
    300 303
                 }
    
    ... ... @@ -315,7 +318,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
    315 318
                 }
    
    316 319
                 showNotificationPermissionPromptIfRequired()
    
    317 320
                 */
    
    318
    -        }
    
    321
    +        //}
    
    319 322
     
    
    320 323
             Performance.processIntentIfPerformanceTest(intent, this)
    
    321 324
     
    
    ... ... @@ -1158,13 +1161,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
    1158 1161
         }
    
    1159 1162
     
    
    1160 1163
         open fun navigateToHome() {
    
    1161
    -        // if (components.fenixOnboarding.userHasBeenOnboarded()) {
    
    1162
    -            navHost.navController.navigate(NavGraphDirections.actionStartupHome())
    
    1163
    -        /*
    
    1164
    -        } else {
    
    1165
    -            navHost.navController.navigate(NavGraphDirections.actionStartupOnboarding())
    
    1166
    -        }
    
    1167
    -        */
    
    1164
    +        navHost.navController.navigate(NavGraphDirections.actionStartupTorbootstrap())
    
    1168 1165
         }
    
    1169 1166
     
    
    1170 1167
         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
    113 113
     import org.mozilla.fenix.search.toolbar.DefaultSearchSelectorController
    
    114 114
     import org.mozilla.fenix.search.toolbar.SearchSelectorMenu
    
    115 115
     import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
    
    116
    +import org.mozilla.fenix.tor.TorBootstrapFragmentDirections
    
    117
    +import org.mozilla.fenix.tor.TorBootstrapStatus
    
    116 118
     import org.mozilla.fenix.tor.bootstrap.TorQuickStart
    
    117 119
     import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
    
    118 120
     import org.mozilla.fenix.utils.allowUndo
    
    ... ... @@ -200,9 +202,9 @@ class HomeFragment : Fragment() {
    200 202
         private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>()
    
    201 203
         private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>()
    
    202 204
         private val searchSelectorBinding = ViewBoundFeatureWrapper<SearchSelectorBinding>()
    
    203
    -    private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
    
    204 205
         private val torQuickStart by lazy { TorQuickStart(requireContext()) }
    
    205
    -    private lateinit var currentMode: CurrentMode
    
    206
    +    private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
    
    207
    +    private lateinit var torBootstrapStatus: TorBootstrapStatus
    
    206 208
     
    
    207 209
         override fun onCreate(savedInstanceState: Bundle?) {
    
    208 210
             // DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
    
    ... ... @@ -233,29 +235,27 @@ class HomeFragment : Fragment() {
    233 235
             val activity = activity as HomeActivity
    
    234 236
             val components = requireComponents
    
    235 237
     
    
    236
    -        val currentWallpaperName = requireContext().settings().currentWallpaperName
    
    237
    -        applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false)
    
    238
    -
    
    239
    -        currentMode = CurrentMode(
    
    240
    -            requireContext(),
    
    238
    +        torBootstrapStatus = TorBootstrapStatus(
    
    241 239
                 torQuickStart,
    
    242 240
                 !BuildConfig.DISABLE_TOR,
    
    243 241
                 components.torController,
    
    244
    -            browsingModeManager,
    
    245 242
                 ::dispatchModeChanges
    
    246 243
             )
    
    247 244
     
    
    245
    +        val currentWallpaperName = requireContext().settings().currentWallpaperName
    
    246
    +        applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false)
    
    247
    +
    
    248 248
             // Splits by full stops or commas and puts the parts in different lines.
    
    249 249
             // Ignoring separators at the end of the string, it is expected
    
    250 250
             // that there are at most two parts (e.g. "Explore. Privately.").
    
    251
    -        val localBinding = binding;
    
    251
    +        val localBinding = binding
    
    252 252
             binding.exploreprivately.text = localBinding
    
    253 253
                 .exploreprivately
    
    254 254
                 .text
    
    255 255
                 ?.replace(" *([.,。।]) *".toRegex(), "$1\n")
    
    256 256
                 ?.trim()
    
    257 257
     
    
    258
    -        components.appStore.dispatch(AppAction.ModeChange(currentMode.getCurrentMode()))
    
    258
    +        components.appStore.dispatch(AppAction.ModeChange(Mode.fromBrowsingMode(browsingModeManager.mode)))
    
    259 259
     
    
    260 260
             lifecycleScope.launch(IO) {
    
    261 261
                 if (requireContext().settings().showPocketRecommendationsFeature) {
    
    ... ... @@ -378,10 +378,6 @@ class HomeFragment : Fragment() {
    378 378
                     registerCollectionStorageObserver = ::registerCollectionStorageObserver,
    
    379 379
                     removeCollectionWithUndo = ::removeCollectionWithUndo,
    
    380 380
                     showTabTray = ::openTabsTray,
    
    381
    -                handleTorBootstrapConnect = ::handleTorBootstrapConnect,
    
    382
    -                cancelTorBootstrap = ::cancelTorBootstrap,
    
    383
    -                initiateTorBootstrap = ::initiateTorBootstrap,
    
    384
    -                openTorNetworkSettings = ::openTorNetworkSettings
    
    385 381
                 ),
    
    386 382
                 recentTabController = DefaultRecentTabsController(
    
    387 383
                     selectTabUseCase = components.useCases.tabsUseCases.selectTab,
    
    ... ... @@ -447,9 +443,6 @@ class HomeFragment : Fragment() {
    447 443
     
    
    448 444
             FxNimbus.features.homescreen.recordExposure()
    
    449 445
     
    
    450
    -        adjustHomeFragmentView(currentMode.getCurrentMode())
    
    451
    -        showSessionControlView()
    
    452
    -
    
    453 446
             // DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
    
    454 447
             requireComponents.core.engine.profiler?.addMarker(
    
    455 448
                 MarkersFragmentLifecycleCallbacks.MARKER_NAME,
    
    ... ... @@ -530,111 +523,6 @@ class HomeFragment : Fragment() {
    530 523
             binding.homeAppBar.setExpanded(true)
    
    531 524
         }
    
    532 525
     
    
    533
    -    // This function should be paired with showSessionControlView()
    
    534
    -    @SuppressWarnings("ComplexMethod", "NestedBlockDepth", "LongMethod")
    
    535
    -    private fun adjustHomeFragmentView(mode: Mode) {
    
    536
    -        binding.sessionControlRecyclerView.apply {
    
    537
    -                visibility = View.INVISIBLE
    
    538
    -        }
    
    539
    -
    
    540
    -        if (mode == Mode.Bootstrap) {
    
    541
    -            binding.sessionControlRecyclerView.apply {
    
    542
    -                setPadding(0, 0, 0, 0)
    
    543
    -                (layoutParams as ViewGroup.MarginLayoutParams).setMargins(0, 0, 0, 0)
    
    544
    -            }
    
    545
    -            binding.homeAppBar.apply {
    
    546
    -                visibility = View.GONE
    
    547
    -
    
    548
    -                // Reset this as SCROLL in case it was previously set as NO_SCROLL after bootstrap
    
    549
    -                children.forEach {
    
    550
    -                    (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
    
    551
    -                        AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
    
    552
    -                }
    
    553
    -            }
    
    554
    -            binding.onionPatternImage.apply {
    
    555
    -                visibility = View.GONE
    
    556
    -            }
    
    557
    -            binding.toolbarLayout.apply {
    
    558
    -                visibility = View.GONE
    
    559
    -            }
    
    560
    -        } else {
    
    561
    -            // Keep synchronized with xml layout (somehow).
    
    562
    -            binding.sessionControlRecyclerView.apply {
    
    563
    -                setPadding(
    
    564
    -                    SESSION_CONTROL_VIEW_PADDING,
    
    565
    -                    SESSION_CONTROL_VIEW_PADDING,
    
    566
    -                    SESSION_CONTROL_VIEW_PADDING,
    
    567
    -                    SESSION_CONTROL_VIEW_PADDING
    
    568
    -                )
    
    569
    -                // Default margin until it is re-set below (either set immediately or after Layout)
    
    570
    -                (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
    
    571
    -                    0,
    
    572
    -                    0,
    
    573
    -                    0,
    
    574
    -                    DEFAULT_ONBOARDING_FINISH_MARGIN
    
    575
    -                )
    
    576
    -            }
    
    577
    -            binding.toolbarLayout.apply {
    
    578
    -                visibility = View.VISIBLE
    
    579
    -                // If the Layout rendering pass was completed, then we have a |height| value,
    
    580
    -                // if it wasn't completed then we have 0.
    
    581
    -                if (height == 0) {
    
    582
    -                    // Set the bottom margin after the toolbar height is defined during Layout
    
    583
    -                    doOnLayout {
    
    584
    -                        val toolbarLayoutHeight = binding.toolbarLayout.height
    
    585
    -                        binding.sessionControlRecyclerView.apply {
    
    586
    -                            (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
    
    587
    -                                0,
    
    588
    -                                0,
    
    589
    -                                0,
    
    590
    -                                toolbarLayoutHeight - SESSION_CONTROL_VIEW_PADDING
    
    591
    -                            )
    
    592
    -                        }
    
    593
    -                    }
    
    594
    -                } else {
    
    595
    -                    binding.sessionControlRecyclerView.apply {
    
    596
    -                        (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
    
    597
    -                            0,
    
    598
    -                            0,
    
    599
    -                            0,
    
    600
    -                            height - SESSION_CONTROL_VIEW_PADDING
    
    601
    -                        )
    
    602
    -                    }
    
    603
    -                }
    
    604
    -            }
    
    605
    -            // Hide the onion pattern during Onboarding, too.
    
    606
    -            // With new onboarding HomeFragment is only reached once onboarding is complete
    
    607
    -            binding.onionPatternImage.apply {
    
    608
    -                visibility = if (currentMode.getCurrentMode() != Mode.Bootstrap) {
    
    609
    -                    View.VISIBLE
    
    610
    -                } else {
    
    611
    -                    View.GONE
    
    612
    -                }
    
    613
    -
    
    614
    -            }
    
    615
    -            binding.homeAppBar.apply {
    
    616
    -                visibility = View.VISIBLE
    
    617
    -
    
    618
    -                children.forEach {
    
    619
    -                    (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
    
    620
    -                        if (currentMode.getCurrentMode() != Mode.Bootstrap) {
    
    621
    -                            AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
    
    622
    -                        } else {
    
    623
    -                            AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
    
    624
    -                        }
    
    625
    -
    
    626
    -                }
    
    627
    -            }
    
    628
    -        }
    
    629
    -    }
    
    630
    -
    
    631
    -    // This function should be paired with adjustHomeFragmentView()
    
    632
    -    private fun showSessionControlView() {
    
    633
    -        binding.sessionControlRecyclerView.apply {
    
    634
    -                visibility = View.VISIBLE
    
    635
    -        }
    
    636
    -    }
    
    637
    -
    
    638 526
         @Suppress("LongMethod", "ComplexMethod")
    
    639 527
         override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    640 528
             // DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
    
    ... ... @@ -880,13 +768,14 @@ class HomeFragment : Fragment() {
    880 768
                 requireComponents.reviewPromptController.promptReview(requireActivity())
    
    881 769
             }
    
    882 770
         }
    
    883
    -       
    
    884
    -    private fun dispatchModeChanges(mode: Mode) {
    
    885
    -        requireComponents.appStore.dispatch(AppAction.ModeChange(mode))
    
    886 771
     
    
    887
    -        adjustHomeFragmentView(mode)
    
    888
    -        updateSessionControlView()
    
    889
    -        showSessionControlView()
    
    772
    +    private fun dispatchModeChanges(isBootstrapping: Boolean) {
    
    773
    +        if (isBootstrapping) {
    
    774
    +            val directions =
    
    775
    +                TorBootstrapFragmentDirections
    
    776
    +                    .actionStartupTorbootstrap()
    
    777
    +            findNavController().navigate(directions)
    
    778
    +        }
    
    890 779
         }
    
    891 780
     
    
    892 781
         @VisibleForTesting
    
    ... ... @@ -912,21 +801,16 @@ class HomeFragment : Fragment() {
    912 801
     
    
    913 802
         override fun onStop() {
    
    914 803
             super.onStop()
    
    915
    -        currentMode.unregisterTorListener()
    
    804
    +        torBootstrapStatus.unregisterTorListener()
    
    916 805
         }
    
    917 806
     
    
    918 807
         override fun onResume() {
    
    919 808
             super.onResume()
    
    809
    +        torBootstrapStatus.registerTorListener()
    
    920 810
             if (browsingModeManager.mode == BrowsingMode.Private) {
    
    921 811
                 activity?.window?.setBackgroundDrawableResource(R.drawable.private_home_background_gradient)
    
    922 812
             }
    
    923 813
     
    
    924
    -        // fenix#40176: Ensure the Home fragment is rendered correctly when we resume.
    
    925
    -        val mode = currentMode.getCurrentMode()
    
    926
    -        adjustHomeFragmentView(mode)
    
    927
    -        updateSessionControlView()
    
    928
    -        showSessionControlView()
    
    929
    -
    
    930 814
             hideToolbar()
    
    931 815
     
    
    932 816
             // Whenever a tab is selected its last access timestamp is automatically updated by A-C.
    
    ... ... @@ -1113,25 +997,6 @@ class HomeFragment : Fragment() {
    1113 997
             }
    
    1114 998
         }
    
    1115 999
     
    
    1116
    -    private fun handleTorBootstrapConnect() {
    
    1117
    -        requireComponents.torController.onTorConnecting()
    
    1118
    -    }
    
    1119
    -
    
    1120
    -    private fun cancelTorBootstrap() {
    
    1121
    -        requireComponents.torController.stopTor()
    
    1122
    -    }
    
    1123
    -
    
    1124
    -    private fun initiateTorBootstrap(withDebugLogging: Boolean = false) {
    
    1125
    -        requireComponents.torController.initiateTorBootstrap(lifecycleScope, withDebugLogging)
    
    1126
    -    }
    
    1127
    -
    
    1128
    -    private fun openTorNetworkSettings() {
    
    1129
    -        val directions =
    
    1130
    -            HomeFragmentDirections
    
    1131
    -                .actionHomeFragmentToTorNetworkSettingsFragment()
    
    1132
    -        findNavController().navigate(directions)
    
    1133
    -    }
    
    1134
    -
    
    1135 1000
         companion object {
    
    1136 1001
             const val ALL_NORMAL_TABS = "all_normal"
    
    1137 1002
             const val ALL_PRIVATE_TABS = "all_private"
    
    ... ... @@ -1153,9 +1018,5 @@ class HomeFragment : Fragment() {
    1153 1018
     
    
    1154 1019
             // Elevation for undo toasts
    
    1155 1020
             internal const val TOAST_ELEVATION = 80f
    
    1156
    -
    
    1157
    -        // Layout
    
    1158
    -        private const val DEFAULT_ONBOARDING_FINISH_MARGIN = 60
    
    1159
    -        private const val SESSION_CONTROL_VIEW_PADDING = 16
    
    1160 1021
         }
    
    1161 1022
     }

  • fenix/app/src/main/java/org/mozilla/fenix/home/Mode.kt
    ... ... @@ -4,12 +4,7 @@
    4 4
     
    
    5 5
     package org.mozilla.fenix.home
    
    6 6
     
    
    7
    -import android.content.Context
    
    8
    -import org.mozilla.fenix.tor.TorController
    
    9
    -import org.mozilla.fenix.tor.TorEvents
    
    10
    -import org.mozilla.fenix.tor.bootstrap.TorQuickStart
    
    11 7
     import org.mozilla.fenix.browser.browsingmode.BrowsingMode
    
    12
    -import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
    
    13 8
     
    
    14 9
     /**
    
    15 10
      * Describes various states of the home fragment UI.
    
    ... ... @@ -17,7 +12,6 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
    17 12
     sealed class Mode {
    
    18 13
         object Normal : Mode()
    
    19 14
         object Private : Mode()
    
    20
    -    object Bootstrap : Mode()
    
    21 15
     
    
    22 16
         companion object {
    
    23 17
             fun fromBrowsingMode(browsingMode: BrowsingMode) = when (browsingMode) {
    
    ... ... @@ -26,48 +20,3 @@ sealed class Mode {
    26 20
             }
    
    27 21
         }
    
    28 22
     }
    29
    -
    
    30
    -@SuppressWarnings("LongParameterList", "TooManyFunctions")
    
    31
    -class CurrentMode(
    
    32
    -    private val context: Context,
    
    33
    -    private val torQuickStart: TorQuickStart,
    
    34
    -    private val shouldStartTor: Boolean,
    
    35
    -    private val torController: TorController,
    
    36
    -    private val browsingModeManager: BrowsingModeManager,
    
    37
    -    private val dispatchModeChanges: (mode: Mode) -> Unit
    
    38
    -) : TorEvents {
    
    39
    -
    
    40
    -    init {
    
    41
    -        torController.registerTorListener(this)
    
    42
    -    }
    
    43
    -
    
    44
    -    fun getCurrentMode() = if (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped)) {
    
    45
    -        Mode.Bootstrap
    
    46
    -    } else {
    
    47
    -        Mode.fromBrowsingMode(browsingModeManager.mode)
    
    48
    -    }
    
    49
    -
    
    50
    -    fun emitModeChanges() {
    
    51
    -        dispatchModeChanges(getCurrentMode())
    
    52
    -    }
    
    53
    -
    
    54
    -    @SuppressWarnings("EmptyFunctionBlock")
    
    55
    -    override fun onTorConnecting() {
    
    56
    -    }
    
    57
    -
    
    58
    -    override fun onTorConnected() {
    
    59
    -        dispatchModeChanges(getCurrentMode())
    
    60
    -    }
    
    61
    -
    
    62
    -    override fun onTorStopped() {
    
    63
    -        dispatchModeChanges(getCurrentMode())
    
    64
    -    }
    
    65
    -
    
    66
    -    @SuppressWarnings("EmptyFunctionBlock")
    
    67
    -    override fun onTorStatusUpdate(entry: String?, status: String?) {
    
    68
    -    }
    
    69
    -
    
    70
    -    fun unregisterTorListener() {
    
    71
    -        torController.unregisterTorListener(this)
    
    72
    -    }
    
    73
    -}

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
    ... ... @@ -34,10 +34,7 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHol
    34 34
     import org.mozilla.fenix.home.sessioncontrol.viewholders.CustomizeHomeButtonViewHolder
    
    35 35
     import org.mozilla.fenix.home.sessioncontrol.viewholders.NoCollectionsMessageViewHolder
    
    36 36
     import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder
    
    37
    -import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapPagerViewHolder
    
    38 37
     import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.MessageCardViewHolder
    
    39
    -import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.TorOnboardingSecurityLevelViewHolder
    
    40
    -import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.TorOnboardingDonateViewHolder
    
    41 38
     import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
    
    42 39
     import mozilla.components.feature.tab.collections.Tab as ComponentTab
    
    43 40
     
    
    ... ... @@ -102,8 +99,6 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
    102 99
         object PrivateBrowsingDescription : AdapterItem(PrivateBrowsingDescriptionViewHolder.LAYOUT_ID)
    
    103 100
         object NoCollectionsMessage : AdapterItem(NoCollectionsMessageViewHolder.LAYOUT_ID)
    
    104 101
     
    
    105
    -    object TorBootstrap : AdapterItem(TorBootstrapPagerViewHolder.LAYOUT_ID)
    
    106
    -
    
    107 102
         object CollectionHeader : AdapterItem(CollectionHeaderViewHolder.LAYOUT_ID)
    
    108 103
         data class CollectionItem(
    
    109 104
             val collection: TabCollection,
    
    ... ... @@ -143,9 +138,6 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
    143 138
     
    
    144 139
         object CustomizeHomeButton : AdapterItem(CustomizeHomeButtonViewHolder.LAYOUT_ID)
    
    145 140
     
    
    146
    -    object TorOnboardingSecurityLevel : AdapterItem(TorOnboardingSecurityLevelViewHolder.LAYOUT_ID)
    
    147
    -    object TorOnboardingDonate : AdapterItem(TorOnboardingDonateViewHolder.LAYOUT_ID)
    
    148
    -
    
    149 141
         object RecentTabsHeader : AdapterItem(RecentTabsHeaderViewHolder.LAYOUT_ID)
    
    150 142
         object RecentTabItem : AdapterItem(RecentTabViewHolder.LAYOUT_ID)
    
    151 143
     
    
    ... ... @@ -293,11 +285,6 @@ class SessionControlAdapter(
    293 285
                     viewLifecycleOwner = viewLifecycleOwner,
    
    294 286
                     interactor = interactor,
    
    295 287
                 )
    
    296
    -            TorBootstrapPagerViewHolder.LAYOUT_ID -> TorBootstrapPagerViewHolder(
    
    297
    -                view,
    
    298
    -                components,
    
    299
    -                interactor
    
    300
    -            )
    
    301 288
                 NoCollectionsMessageViewHolder.LAYOUT_ID ->
    
    302 289
                     NoCollectionsMessageViewHolder(
    
    303 290
                         view,
    
    ... ... @@ -307,15 +294,6 @@ class SessionControlAdapter(
    307 294
                         interactor,
    
    308 295
                     )
    
    309 296
                 BottomSpacerViewHolder.LAYOUT_ID -> BottomSpacerViewHolder(view)
    
    310
    -
    
    311
    -            TorOnboardingSecurityLevelViewHolder.LAYOUT_ID -> TorOnboardingSecurityLevelViewHolder(
    
    312
    -                view,
    
    313
    -                interactor
    
    314
    -            )
    
    315
    -            TorOnboardingDonateViewHolder.LAYOUT_ID -> TorOnboardingDonateViewHolder(
    
    316
    -                view,
    
    317
    -                interactor
    
    318
    -            )
    
    319 297
                 else -> throw IllegalStateException()
    
    320 298
             }
    
    321 299
         }
    

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
    ... ... @@ -134,21 +134,6 @@ interface SessionControlController {
    134 134
          */
    
    135 135
         fun handleTopSiteLongClicked(topSite: TopSite)
    
    136 136
     
    
    137
    -    /**
    
    138
    -     * @see [OnboardingInteractor.onOpenSettingsClicked]
    
    139
    -     */
    
    140
    -    fun handleOpenSettingsClicked()
    
    141
    -
    
    142
    -    /**
    
    143
    -     * @see [OnboardingInteractor.onOpenSecurityLevelSettingsClicked]
    
    144
    -     */
    
    145
    -    fun handleOpenSecurityLevelSettingsClicked()
    
    146
    -
    
    147
    -    /**
    
    148
    -     * @see [OnboardingInteractor.onDonateClicked]
    
    149
    -     */
    
    150
    -    fun handleDonateClicked()
    
    151
    -
    
    152 137
         /**
    
    153 138
          * @see [CollectionInteractor.onToggleCollectionExpanded]
    
    154 139
          */
    
    ... ... @@ -188,31 +173,6 @@ interface SessionControlController {
    188 173
          * @see [SessionControlInteractor.reportSessionMetrics]
    
    189 174
          */
    
    190 175
         fun handleReportSessionMetrics(state: AppState)
    
    191
    -
    
    192
    -    /**
    
    193
    -     * @see [TorBootstrapInteractor.onTorBootstrapConnectClicked]
    
    194
    -     */
    
    195
    -    fun handleTorBootstrapConnectClicked()
    
    196
    -
    
    197
    -    /**
    
    198
    -     * @see [TorBootstrapInteractor.onTorStopBootstrapping]
    
    199
    -     */
    
    200
    -    fun handleTorStopBootstrapping()
    
    201
    -
    
    202
    -    /**
    
    203
    -     * @see [TorBootstrapInteractor.onTorStartBootstrapping]
    
    204
    -     */
    
    205
    -    fun handleTorStartBootstrapping()
    
    206
    -
    
    207
    -    /**
    
    208
    -     * @see [TorBootstrapInteractor.onTorStartDebugBootstrapping]
    
    209
    -     */
    
    210
    -    fun handleTorStartDebugBootstrapping()
    
    211
    -
    
    212
    -    /**
    
    213
    -     * @see [TorBootstrapInteractor.onTorBootstrapNetworkSettingsClicked]
    
    214
    -     */
    
    215
    -    fun handleTorNetworkSettingsClicked()
    
    216 176
     }
    
    217 177
     
    
    218 178
     @Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
    
    ... ... @@ -233,10 +193,6 @@ class DefaultSessionControlController(
    233 193
         private val registerCollectionStorageObserver: () -> Unit,
    
    234 194
         private val removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit,
    
    235 195
         private val showTabTray: () -> Unit,
    
    236
    -    private val handleTorBootstrapConnect: () -> Unit,
    
    237
    -    private val initiateTorBootstrap: (Boolean) -> Unit,
    
    238
    -    private val cancelTorBootstrap: () -> Unit,
    
    239
    -    private val openTorNetworkSettings: () -> Unit
    
    240 196
     ) : SessionControlController {
    
    241 197
     
    
    242 198
         override fun handleCollectionAddTabTapped(collection: TabCollection) {
    
    ... ... @@ -511,25 +467,6 @@ class DefaultSessionControlController(
    511 467
                 }
    
    512 468
             }
    
    513 469
         }
    
    514
    -
    
    515
    -    override fun handleOpenSettingsClicked() {
    
    516
    -        val directions = HomeFragmentDirections.actionGlobalPrivateBrowsingFragment()
    
    517
    -        navController.nav(R.id.homeFragment, directions)
    
    518
    -    }
    
    519
    -
    
    520
    -    override fun handleOpenSecurityLevelSettingsClicked() {
    
    521
    -        val directions = HomeFragmentDirections.actionGlobalTorSecurityLevelFragment()
    
    522
    -        navController.nav(R.id.homeFragment, directions)
    
    523
    -    }
    
    524
    -
    
    525
    -    override fun handleDonateClicked() {
    
    526
    -        activity.openToBrowserAndLoad(
    
    527
    -            searchTermOrURL = SupportUtils.DONATE_URL,
    
    528
    -            newTab = true,
    
    529
    -            from = BrowserDirection.FromHome
    
    530
    -        )
    
    531
    -    }
    
    532
    -
    
    533 470
         override fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
    
    534 471
             appStore.dispatch(AppAction.CollectionExpanded(collection, expand))
    
    535 472
         }
    
    ... ... @@ -601,24 +538,4 @@ class DefaultSessionControlController(
    601 538
     
    
    602 539
             RecentBookmarks.recentBookmarksCount.set(state.recentBookmarks.size.toLong())
    
    603 540
         }
    
    604
    -
    
    605
    -    override fun handleTorBootstrapConnectClicked() {
    
    606
    -        handleTorBootstrapConnect()
    
    607
    -    }
    
    608
    -
    
    609
    -    override fun handleTorStopBootstrapping() {
    
    610
    -        cancelTorBootstrap()
    
    611
    -    }
    
    612
    -
    
    613
    -    override fun handleTorStartBootstrapping() {
    
    614
    -        initiateTorBootstrap(false)
    
    615
    -    }
    
    616
    -
    
    617
    -    override fun handleTorStartDebugBootstrapping() {
    
    618
    -        initiateTorBootstrap(true)
    
    619
    -    }
    
    620
    -
    
    621
    -    override fun handleTorNetworkSettingsClicked() {
    
    622
    -        openTorNetworkSettings()
    
    623
    -    }
    
    624 541
     }

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
    ... ... @@ -129,26 +129,6 @@ interface CollectionInteractor {
    129 129
         fun onRemoveCollectionsPlaceholder()
    
    130 130
     }
    
    131 131
     
    
    132
    -/**
    
    133
    - * Interface for onboarding related actions in the [SessionControlInteractor].
    
    134
    - */
    
    135
    -interface OnboardingInteractor {
    
    136
    -    /**
    
    137
    -     * Hides the onboarding and navigates to Search. Called when a user clicks on the "Start Browsing" button.
    
    138
    -     */
    
    139
    -    fun onStartBrowsingClicked()
    
    140
    -
    
    141
    -    /**
    
    142
    -     * Hides the onboarding and navigates to Settings. Called when a user clicks on the "Open settings" button.
    
    143
    -     */
    
    144
    -    fun onOpenSettingsClicked()
    
    145
    -
    
    146
    -    /**
    
    147
    -     * Opens a custom tab to privacy notice url. Called when a user clicks on the "read our privacy notice" button.
    
    148
    -     */
    
    149
    -    fun onDonateClicked()
    
    150
    -}
    
    151
    -
    
    152 132
     interface CustomizeHomeIteractor {
    
    153 133
         /**
    
    154 134
          * Opens the customize home settings page.
    
    ... ... @@ -156,34 +136,6 @@ interface CustomizeHomeIteractor {
    156 136
         fun openCustomizeHomePage()
    
    157 137
     }
    
    158 138
     
    
    159
    -interface TorBootstrapInteractor {
    
    160
    -    /**
    
    161
    -     * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
    
    162
    -     */
    
    163
    -    fun onTorBootstrapConnectClicked()
    
    164
    -
    
    165
    -    /**
    
    166
    -     * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
    
    167
    -     */
    
    168
    -    fun onTorStartBootstrapping()
    
    169
    -
    
    170
    -    /**
    
    171
    -     * Stop Tor bootstrapping. Called when a user clicks on the "settings" cog/button.
    
    172
    -     */
    
    173
    -    fun onTorStopBootstrapping()
    
    174
    -
    
    175
    -    /**
    
    176
    -     * Initiates Tor bootstrapping with debug logging. Called when bootstrapping fails with
    
    177
    -     * the control.txt file not existing.
    
    178
    -     */
    
    179
    -    fun onTorStartDebugBootstrapping()
    
    180
    -
    
    181
    -    /**
    
    182
    -     * Open Tor Network Settings preference screen
    
    183
    -     */
    
    184
    -    fun onTorBootstrapNetworkSettingsClicked()
    
    185
    -}
    
    186
    -
    
    187 139
     /**
    
    188 140
      * Interface for top site related actions in the [SessionControlInteractor].
    
    189 141
      */
    
    ... ... @@ -295,7 +247,6 @@ class SessionControlInteractor(
    295 247
         PocketStoriesInteractor,
    
    296 248
         PrivateBrowsingInteractor,
    
    297 249
         SearchSelectorInteractor,
    
    298
    -    TorBootstrapInteractor,
    
    299 250
         WallpaperInteractor {
    
    300 251
     
    
    301 252
         override fun onCollectionAddTabTapped(collection: TabCollection) {
    
    ... ... @@ -358,15 +309,6 @@ class SessionControlInteractor(
    358 309
             return controller.handleShowWallpapersOnboardingDialog(state)
    
    359 310
         }
    
    360 311
     
    
    361
    -    // TODO: Do these still work, if not overrides, cus parent class dropped, are they wired in still?
    
    362
    -    fun onOpenSettingsClicked() {
    
    363
    -        controller.handleOpenSettingsClicked()
    
    364
    -    }
    
    365
    -
    
    366
    -    fun onDonateClicked() {
    
    367
    -        controller.handleDonateClicked()
    
    368
    -    }
    
    369
    -
    
    370 312
         override fun onToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
    
    371 313
             controller.handleToggleCollectionExpanded(collection, expand)
    
    372 314
         }
    
    ... ... @@ -500,24 +442,4 @@ class SessionControlInteractor(
    500 442
         override fun onMenuItemTapped(item: SearchSelectorMenu.Item) {
    
    501 443
             searchSelectorController.handleMenuItemTapped(item)
    
    502 444
         }
    
    503
    -
    
    504
    -    override fun onTorBootstrapConnectClicked() {
    
    505
    -        controller.handleTorBootstrapConnectClicked()
    
    506
    -    }
    
    507
    -
    
    508
    -    override fun onTorStopBootstrapping() {
    
    509
    -        controller.handleTorStopBootstrapping()
    
    510
    -    }
    
    511
    -
    
    512
    -    override fun onTorStartBootstrapping() {
    
    513
    -        controller.handleTorStartBootstrapping()
    
    514
    -    }
    
    515
    -
    
    516
    -    override fun onTorStartDebugBootstrapping() {
    
    517
    -        controller.handleTorStartDebugBootstrapping()
    
    518
    -    }
    
    519
    -
    
    520
    -    override fun onTorBootstrapNetworkSettingsClicked() {
    
    521
    -        controller.handleTorNetworkSettingsClicked()
    
    522
    -    }
    
    523 445
     }

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
    ... ... @@ -126,15 +126,6 @@ private fun showCollections(
    126 126
     
    
    127 127
     private fun privateModeAdapterItems() = listOf(AdapterItem.PrivateBrowsingDescription)
    
    128 128
     
    
    129
    -private fun bootstrapAdapterItems() = listOf(AdapterItem.TorBootstrap)
    
    130
    -
    
    131
    -private fun torOnboardingAdapterItems() =
    
    132
    -    listOf(
    
    133
    -        AdapterItem.TorOnboardingSecurityLevel,
    
    134
    -        AdapterItem.TorOnboardingDonate,
    
    135
    -        // AdapterItem.OnboardingFinish
    
    136
    -    )
    
    137
    -
    
    138 129
     private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when (mode) {
    
    139 130
         is Mode.Normal -> normalModeAdapterItems(
    
    140 131
             settings,
    
    ... ... @@ -151,7 +142,6 @@ private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when
    151 142
             firstFrameDrawn,
    
    152 143
         )
    
    153 144
         is Mode.Private -> privateModeAdapterItems()
    
    154
    -    is Mode.Bootstrap -> bootstrapAdapterItems()
    
    155 145
     }
    
    156 146
     
    
    157 147
     private fun collectionTabItems(collection: TabCollection) =
    

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingDonateViewHolder.kt deleted
    1
    -/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    - * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    -
    
    5
    -package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
    
    6
    -
    
    7
    -import android.view.View
    
    8
    -import androidx.recyclerview.widget.RecyclerView
    
    9
    -import org.mozilla.fenix.R
    
    10
    -import org.mozilla.fenix.databinding.TorOnboardingDonateBinding
    
    11
    -import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
    
    12
    -
    
    13
    -class TorOnboardingDonateViewHolder(
    
    14
    -    view: View,
    
    15
    -    private val interactor: SessionControlInteractor
    
    16
    -) : RecyclerView.ViewHolder(view) {
    
    17
    -
    
    18
    -    init {
    
    19
    -        val binding = TorOnboardingDonateBinding.bind(view)
    
    20
    -        binding.donateNowButton.setOnClickListener {
    
    21
    -            interactor.onDonateClicked()
    
    22
    -        }
    
    23
    -    }
    
    24
    -
    
    25
    -    companion object {
    
    26
    -        const val LAYOUT_ID = R.layout.tor_onboarding_donate
    
    27
    -    }
    
    28
    -}

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt deleted
    1
    -/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    - * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    -
    
    5
    -package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
    
    6
    -
    
    7
    -import android.view.View
    
    8
    -import androidx.recyclerview.widget.RecyclerView
    
    9
    -import org.mozilla.fenix.R
    
    10
    -import org.mozilla.fenix.databinding.TorOnboardingSecurityLevelBinding
    
    11
    -import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
    
    12
    -import org.mozilla.fenix.ext.components
    
    13
    -import org.mozilla.fenix.onboarding.OnboardingRadioButton
    
    14
    -import org.mozilla.fenix.tor.SecurityLevel
    
    15
    -import org.mozilla.fenix.tor.SecurityLevelUtil
    
    16
    -import org.mozilla.fenix.utils.view.addToRadioGroup
    
    17
    -
    
    18
    -class TorOnboardingSecurityLevelViewHolder(
    
    19
    -    view: View,
    
    20
    -    private val interactor: SessionControlInteractor
    
    21
    -) : RecyclerView.ViewHolder(view) {
    
    22
    -
    
    23
    -    private var _binding: TorOnboardingSecurityLevelBinding? = null
    
    24
    -    private val binding get() = _binding!!
    
    25
    -
    
    26
    -    private var standardSecurityLevel: OnboardingRadioButton
    
    27
    -    private var saferSecurityLevel: OnboardingRadioButton
    
    28
    -    private var safestSecurityLevel: OnboardingRadioButton
    
    29
    -
    
    30
    -    init {
    
    31
    -        _binding = TorOnboardingSecurityLevelBinding.bind(view)
    
    32
    -        binding.headerText.setOnboardingIcon(R.drawable.ic_onboarding_tracking_protection)
    
    33
    -
    
    34
    -        standardSecurityLevel = binding.securityLevelStandardOption
    
    35
    -        saferSecurityLevel = binding.securityLevelSaferOption
    
    36
    -        safestSecurityLevel = binding.securityLevelSafestOption
    
    37
    -
    
    38
    -        binding.descriptionText.text = view.context.getString(
    
    39
    -            R.string.tor_onboarding_security_level_description
    
    40
    -        )
    
    41
    -
    
    42
    -        setupRadioGroup(view)
    
    43
    -
    
    44
    -    }
    
    45
    -
    
    46
    -    private fun setupRadioGroup(view: View) {
    
    47
    -
    
    48
    -        addToRadioGroup(standardSecurityLevel, saferSecurityLevel, safestSecurityLevel)
    
    49
    -
    
    50
    -        val securityLevel = try {
    
    51
    -            SecurityLevelUtil.getSecurityLevelFromInt(
    
    52
    -                view.context.components.core.engine.settings.torSecurityLevel
    
    53
    -            )
    
    54
    -        } catch (e: IllegalStateException) {
    
    55
    -            SecurityLevel.STANDARD
    
    56
    -        }
    
    57
    -
    
    58
    -        standardSecurityLevel.isChecked = securityLevel == SecurityLevel.STANDARD
    
    59
    -        safestSecurityLevel.isChecked = securityLevel == SecurityLevel.SAFEST
    
    60
    -        saferSecurityLevel.isChecked = securityLevel == SecurityLevel.SAFER
    
    61
    -
    
    62
    -        standardSecurityLevel.onClickListener {
    
    63
    -            updateSecurityLevel(SecurityLevel.STANDARD, view)
    
    64
    -        }
    
    65
    -
    
    66
    -        saferSecurityLevel.onClickListener {
    
    67
    -            updateSecurityLevel(SecurityLevel.SAFER, view)
    
    68
    -        }
    
    69
    -
    
    70
    -        safestSecurityLevel.onClickListener {
    
    71
    -            updateSecurityLevel(SecurityLevel.SAFEST, view)
    
    72
    -        }
    
    73
    -
    
    74
    -        updateSecurityLevel(securityLevel, view)
    
    75
    -    }
    
    76
    -
    
    77
    -    private fun updateSecurityLevel(newLevel: SecurityLevel, view: View) {
    
    78
    -        val resources = view.context.resources
    
    79
    -        val securityLevel = when (newLevel) {
    
    80
    -            SecurityLevel.STANDARD -> resources.getString(R.string.tor_security_level_standard_option)
    
    81
    -            SecurityLevel.SAFER -> resources.getString(R.string.tor_security_level_safer_option)
    
    82
    -            SecurityLevel.SAFEST -> resources.getString(R.string.tor_security_level_safest_option)
    
    83
    -        }
    
    84
    -        binding.currentLevel.text = resources.getString(
    
    85
    -            R.string.tor_onboarding_chosen_security_level_label, securityLevel
    
    86
    -        )
    
    87
    -        view.context.components.let {
    
    88
    -            it.core.engine.settings.torSecurityLevel = newLevel.intRepresentation
    
    89
    -        }
    
    90
    -    }
    
    91
    -
    
    92
    -    companion object {
    
    93
    -        const val LAYOUT_ID = R.layout.tor_onboarding_security_level
    
    94
    -    }
    
    95
    -}

  • fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.tor
    
    6
    +
    
    7
    +import android.os.Bundle
    
    8
    +import android.view.LayoutInflater
    
    9
    +import android.view.View
    
    10
    +import android.view.ViewGroup
    
    11
    +import androidx.annotation.VisibleForTesting
    
    12
    +import androidx.core.view.children
    
    13
    +import androidx.fragment.app.Fragment
    
    14
    +import androidx.lifecycle.lifecycleScope
    
    15
    +import org.mozilla.fenix.BuildConfig
    
    16
    +import org.mozilla.fenix.databinding.FragmentHomeBinding
    
    17
    +import org.mozilla.fenix.ext.requireComponents
    
    18
    +import org.mozilla.fenix.tor.bootstrap.TorQuickStart
    
    19
    +import org.mozilla.fenix.tor.interactor.DefaultTorBootstrapInteractor
    
    20
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    21
    +import androidx.navigation.fragment.findNavController
    
    22
    +import com.google.android.material.appbar.AppBarLayout
    
    23
    +import org.mozilla.fenix.ext.components
    
    24
    +import org.mozilla.fenix.ext.hideToolbar
    
    25
    +import org.mozilla.fenix.tor.controller.DefaultTorBootstrapController
    
    26
    +import org.mozilla.fenix.tor.view.TorBootstrapView
    
    27
    +
    
    28
    +
    
    29
    +@Suppress("TooManyFunctions", "LargeClass")
    
    30
    +class TorBootstrapFragment : Fragment() {
    
    31
    +    private val torQuickStart by lazy { TorQuickStart(requireContext()) }
    
    32
    +
    
    33
    +    internal var _binding: FragmentHomeBinding? = null
    
    34
    +    private val binding get() = _binding!!
    
    35
    +
    
    36
    +
    
    37
    +    private var torBootstrapView: TorBootstrapView? = null
    
    38
    +
    
    39
    +    private var _torBootstrapInteractor: TorBootstrapInteractor? = null
    
    40
    +    private val torBootstrapInteractor: TorBootstrapInteractor
    
    41
    +        get() = _torBootstrapInteractor!!
    
    42
    +
    
    43
    +    private lateinit var torBootstrapStatus: TorBootstrapStatus
    
    44
    +
    
    45
    +
    
    46
    +    @Suppress("LongMethod")
    
    47
    +    override fun onCreateView(
    
    48
    +        inflater: LayoutInflater,
    
    49
    +        container: ViewGroup?,
    
    50
    +        savedInstanceState: Bundle?,
    
    51
    +    ): View {
    
    52
    +        _binding = FragmentHomeBinding.inflate(inflater, container, false)
    
    53
    +        val components = requireComponents
    
    54
    +
    
    55
    +        torBootstrapStatus = TorBootstrapStatus(
    
    56
    +            torQuickStart,
    
    57
    +            !BuildConfig.DISABLE_TOR,
    
    58
    +            components.torController,
    
    59
    +            ::dispatchModeChanges
    
    60
    +        )
    
    61
    +
    
    62
    +        if (!torBootstrapStatus.isBootstrapping()) {
    
    63
    +            openHome()
    
    64
    +        }
    
    65
    +
    
    66
    +        // Was _sessionControlInteractor
    
    67
    +        _torBootstrapInteractor = DefaultTorBootstrapInteractor(
    
    68
    +            controller = DefaultTorBootstrapController(
    
    69
    +                handleTorBootstrapConnect = ::handleTorBootstrapConnect,
    
    70
    +                cancelTorBootstrap = ::cancelTorBootstrap,
    
    71
    +                initiateTorBootstrap = ::initiateTorBootstrap,
    
    72
    +                openTorNetworkSettings = ::openTorNetworkSettings
    
    73
    +            ),
    
    74
    +        )
    
    75
    +
    
    76
    +        torBootstrapView = TorBootstrapView(
    
    77
    +            containerView = binding.sessionControlRecyclerView,
    
    78
    +            viewLifecycleOwner = viewLifecycleOwner,
    
    79
    +            interactor = torBootstrapInteractor,
    
    80
    +        )
    
    81
    +
    
    82
    +        adjustHomeFragmentView()
    
    83
    +        updateSessionControlView()
    
    84
    +        showSessionControlView()
    
    85
    +
    
    86
    +        return binding.root
    
    87
    +    }
    
    88
    +
    
    89
    +    private fun updateSessionControlView() {
    
    90
    +        torBootstrapView?.update(requireContext().components.appStore.state)
    
    91
    +    }
    
    92
    +
    
    93
    +    // This function should be paired with showSessionControlView()
    
    94
    +    private fun adjustHomeFragmentView() {
    
    95
    +        binding.sessionControlRecyclerView.apply {
    
    96
    +            visibility = View.INVISIBLE
    
    97
    +        }
    
    98
    +
    
    99
    +        binding.sessionControlRecyclerView.apply {
    
    100
    +            setPadding(0, 0, 0, 0)
    
    101
    +            (layoutParams as ViewGroup.MarginLayoutParams).setMargins(0, 0, 0, 0)
    
    102
    +        }
    
    103
    +
    
    104
    +        binding.homeAppBar.apply {
    
    105
    +            visibility = View.GONE
    
    106
    +
    
    107
    +            // Reset this as SCROLL in case it was previously set as NO_SCROLL after bootstrap
    
    108
    +            children.forEach {
    
    109
    +                (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
    
    110
    +                    AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
    
    111
    +            }
    
    112
    +        }
    
    113
    +        binding.onionPatternImage.apply {
    
    114
    +            visibility = View.GONE
    
    115
    +        }
    
    116
    +        binding.toolbarLayout.apply {
    
    117
    +            visibility = View.GONE
    
    118
    +        }
    
    119
    +    }
    
    120
    +
    
    121
    +    // This function should be paired with adjustHomeFragmentView()
    
    122
    +    private fun showSessionControlView() {
    
    123
    +        binding.sessionControlRecyclerView.apply {
    
    124
    +            visibility = View.VISIBLE
    
    125
    +        }
    
    126
    +    }
    
    127
    +
    
    128
    +    private fun dispatchModeChanges(isBootstrapping: Boolean) {
    
    129
    +        //requireComponents.appStore.dispatch(AppAction.ModeChange(mode))
    
    130
    +        if (!isBootstrapping) {
    
    131
    +            openHome()
    
    132
    +        } else {
    
    133
    +            adjustHomeFragmentView()
    
    134
    +            updateSessionControlView()
    
    135
    +            showSessionControlView()
    
    136
    +        }
    
    137
    +    }
    
    138
    +
    
    139
    +    override fun onStop() {
    
    140
    +        super.onStop()
    
    141
    +        torBootstrapStatus.unregisterTorListener()
    
    142
    +    }
    
    143
    +
    
    144
    +    override fun onResume() {
    
    145
    +        super.onResume()
    
    146
    +
    
    147
    +        torBootstrapStatus.registerTorListener()
    
    148
    +
    
    149
    +        // fenix#40176: Ensure the Home fragment is rendered correctly when we resume.
    
    150
    +        val isBootstraping = torBootstrapStatus.isBootstrapping()
    
    151
    +
    
    152
    +        if (!isBootstraping) {
    
    153
    +            openHome()
    
    154
    +        }
    
    155
    +
    
    156
    +        adjustHomeFragmentView()
    
    157
    +        updateSessionControlView()
    
    158
    +        showSessionControlView()
    
    159
    +
    
    160
    +        hideToolbar()
    
    161
    +
    
    162
    +        // Whenever a tab is selected its last access timestamp is automatically updated by A-C.
    
    163
    +        // However, in the case of resuming the app to the home fragment, we already have an
    
    164
    +        // existing selected tab, but its last access timestamp is outdated. No action is
    
    165
    +        // triggered to cause an automatic update on warm start (no tab selection occurs). So we
    
    166
    +        // update it manually here.
    
    167
    +        requireComponents.useCases.sessionUseCases.updateLastAccess()
    
    168
    +    }
    
    169
    +
    
    170
    +    private fun handleTorBootstrapConnect() {
    
    171
    +        requireComponents.torController.onTorConnecting()
    
    172
    +    }
    
    173
    +
    
    174
    +    private fun cancelTorBootstrap() {
    
    175
    +        requireComponents.torController.stopTor()
    
    176
    +    }
    
    177
    +
    
    178
    +    private fun initiateTorBootstrap(withDebugLogging: Boolean = false) {
    
    179
    +        requireComponents.torController.initiateTorBootstrap(lifecycleScope, withDebugLogging)
    
    180
    +    }
    
    181
    +
    
    182
    +    private fun openTorNetworkSettings() {
    
    183
    +        val directions =
    
    184
    +            TorBootstrapFragmentDirections.actionTorbootstrapFragmentToTorNetworkSettingsFragment()
    
    185
    +        findNavController().navigate(directions)
    
    186
    +    }
    
    187
    +
    
    188
    +    private fun openHome() {
    
    189
    +        val directions =
    
    190
    +            TorBootstrapFragmentDirections
    
    191
    +                .actionStartupHome()
    
    192
    +        findNavController().navigate(directions)
    
    193
    +    }
    
    194
    +
    
    195
    +}

  • fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.tor
    
    6
    +
    
    7
    +import org.mozilla.fenix.tor.bootstrap.TorQuickStart
    
    8
    +
    
    9
    +@SuppressWarnings("LongParameterList", "TooManyFunctions")
    
    10
    +class TorBootstrapStatus(
    
    11
    +        private val torQuickStart: TorQuickStart,
    
    12
    +        private val shouldStartTor: Boolean,
    
    13
    +        private val torController: TorController,
    
    14
    +        private val dispatchModeChanges: (isShouldBootstrap: Boolean) -> Unit
    
    15
    +    ) : TorEvents {
    
    16
    +
    
    17
    +        init {
    
    18
    +            torController.registerTorListener(this)
    
    19
    +        }
    
    20
    +
    
    21
    +        fun isBootstrapping() = (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped))
    
    22
    +
    
    23
    +
    
    24
    +        @SuppressWarnings("EmptyFunctionBlock")
    
    25
    +        override fun onTorConnecting() {
    
    26
    +        }
    
    27
    +
    
    28
    +        override fun onTorConnected() {
    
    29
    +            dispatchModeChanges(isBootstrapping())
    
    30
    +        }
    
    31
    +
    
    32
    +        override fun onTorStopped() {
    
    33
    +            dispatchModeChanges(isBootstrapping())
    
    34
    +        }
    
    35
    +
    
    36
    +        @SuppressWarnings("EmptyFunctionBlock")
    
    37
    +        override fun onTorStatusUpdate(entry: String?, status: String?) {
    
    38
    +        }
    
    39
    +
    
    40
    +        fun unregisterTorListener() {
    
    41
    +            torController.unregisterTorListener(this)
    
    42
    +        }
    
    43
    +
    
    44
    +    fun registerTorListener() {
    
    45
    +        torController.registerTorListener(this)
    
    46
    +    }
    
    47
    +
    
    48
    +}

  • fenix/app/src/main/java/org/mozilla/fenix/tor/controller/TorBootstrapController.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.tor.controller
    
    6
    +
    
    7
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    8
    +
    
    9
    +interface TorBootstrapController {
    
    10
    +    /**
    
    11
    +     * @see [TorBootstrapInteractor.onTorBootstrapConnectClicked]
    
    12
    +     */
    
    13
    +    fun handleTorBootstrapConnectClicked()
    
    14
    +
    
    15
    +    /**
    
    16
    +     * @see [TorBootstrapInteractor.onTorStopBootstrapping]
    
    17
    +     */
    
    18
    +    fun handleTorStopBootstrapping()
    
    19
    +
    
    20
    +    /**
    
    21
    +     * @see [TorBootstrapInteractor.onTorStartBootstrapping]
    
    22
    +     */
    
    23
    +    fun handleTorStartBootstrapping()
    
    24
    +
    
    25
    +    /**
    
    26
    +     * @see [TorBootstrapInteractor.onTorStartDebugBootstrapping]
    
    27
    +     */
    
    28
    +    fun handleTorStartDebugBootstrapping()
    
    29
    +
    
    30
    +    /**
    
    31
    +     * @see [TorBootstrapInteractor.onTorBootstrapNetworkSettingsClicked]
    
    32
    +     */
    
    33
    +    fun handleTorNetworkSettingsClicked()
    
    34
    +
    
    35
    +
    
    36
    +}
    
    37
    +
    
    38
    +class DefaultTorBootstrapController(
    
    39
    +    private val handleTorBootstrapConnect: () -> Unit,
    
    40
    +    private val initiateTorBootstrap: (Boolean) -> Unit,
    
    41
    +    private val cancelTorBootstrap: () -> Unit,
    
    42
    +    private val openTorNetworkSettings: () -> Unit
    
    43
    +) : TorBootstrapController {
    
    44
    +    override fun handleTorBootstrapConnectClicked() {
    
    45
    +        handleTorBootstrapConnect()
    
    46
    +    }
    
    47
    +
    
    48
    +    override fun handleTorStopBootstrapping() {
    
    49
    +        cancelTorBootstrap()
    
    50
    +    }
    
    51
    +
    
    52
    +    override fun handleTorStartBootstrapping() {
    
    53
    +        initiateTorBootstrap(false)
    
    54
    +    }
    
    55
    +
    
    56
    +    override fun handleTorStartDebugBootstrapping() {
    
    57
    +        initiateTorBootstrap(true)
    
    58
    +    }
    
    59
    +
    
    60
    +    override fun handleTorNetworkSettingsClicked() {
    
    61
    +        openTorNetworkSettings()
    
    62
    +    }
    
    63
    +}

  • fenix/app/src/main/java/org/mozilla/fenix/tor/interactor/TorBootstrapInteractor.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.tor.interactor
    
    6
    +
    
    7
    +import org.mozilla.fenix.tor.controller.TorBootstrapController
    
    8
    +
    
    9
    +interface TorBootstrapInteractor {
    
    10
    +    /**
    
    11
    +     * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
    
    12
    +     */
    
    13
    +    fun onTorBootstrapConnectClicked()
    
    14
    +
    
    15
    +    /**
    
    16
    +     * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
    
    17
    +     */
    
    18
    +    fun onTorStartBootstrapping()
    
    19
    +
    
    20
    +    /**
    
    21
    +     * Stop Tor bootstrapping. Called when a user clicks on the "settings" cog/button.
    
    22
    +     */
    
    23
    +    fun onTorStopBootstrapping()
    
    24
    +
    
    25
    +    /**
    
    26
    +     * Initiates Tor bootstrapping with debug logging. Called when bootstrapping fails with
    
    27
    +     * the control.txt file not existing.
    
    28
    +     */
    
    29
    +    fun onTorStartDebugBootstrapping()
    
    30
    +
    
    31
    +    /**
    
    32
    +     * Open Tor Network Settings preference screen
    
    33
    +     */
    
    34
    +    fun onTorBootstrapNetworkSettingsClicked()
    
    35
    +}
    
    36
    +
    
    37
    +class DefaultTorBootstrapInteractor(
    
    38
    +    private val controller: TorBootstrapController,
    
    39
    +) : TorBootstrapInteractor {
    
    40
    +
    
    41
    +    override fun onTorBootstrapConnectClicked() {
    
    42
    +        controller.handleTorBootstrapConnectClicked()
    
    43
    +    }
    
    44
    +
    
    45
    +    override fun onTorStopBootstrapping() {
    
    46
    +        controller.handleTorStopBootstrapping()
    
    47
    +    }
    
    48
    +
    
    49
    +    override fun onTorStartBootstrapping() {
    
    50
    +        controller.handleTorStartBootstrapping()
    
    51
    +    }
    
    52
    +
    
    53
    +    override fun onTorStartDebugBootstrapping() {
    
    54
    +        controller.handleTorStartDebugBootstrapping()
    
    55
    +    }
    
    56
    +
    
    57
    +    override fun onTorBootstrapNetworkSettingsClicked() {
    
    58
    +        controller.handleTorNetworkSettingsClicked()
    
    59
    +    }
    
    60
    +}

  • fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapAdapter.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.tor.view
    
    6
    +
    
    7
    +import android.view.LayoutInflater
    
    8
    +import android.view.ViewGroup
    
    9
    +import androidx.annotation.LayoutRes
    
    10
    +import androidx.lifecycle.LifecycleOwner
    
    11
    +import androidx.recyclerview.widget.DiffUtil
    
    12
    +import androidx.recyclerview.widget.ListAdapter
    
    13
    +import androidx.recyclerview.widget.RecyclerView
    
    14
    +import org.mozilla.fenix.components.Components
    
    15
    +import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
    
    16
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    17
    +
    
    18
    +sealed class AdapterItem(@LayoutRes val viewType: Int) {
    
    19
    +    object TorBootstrap : AdapterItem(TorBootstrapPagerViewHolder.LAYOUT_ID)
    
    20
    +
    
    21
    +
    
    22
    +    open fun sameAs(other: AdapterItem) = this::class == other::class
    
    23
    +    open fun getChangePayload(newItem: AdapterItem): Any? = null
    
    24
    +    open fun contentsSameAs(other: AdapterItem) = this::class == other::class
    
    25
    +
    
    26
    +}
    
    27
    +
    
    28
    +class AdapterItemDiffCallback : DiffUtil.ItemCallback<AdapterItem>() {
    
    29
    +    override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
    
    30
    +        oldItem.sameAs(newItem)
    
    31
    +
    
    32
    +    @Suppress("DiffUtilEquals")
    
    33
    +    override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
    
    34
    +        oldItem.contentsSameAs(newItem)
    
    35
    +
    
    36
    +    override fun getChangePayload(oldItem: AdapterItem, newItem: AdapterItem): Any? {
    
    37
    +        return oldItem.getChangePayload(newItem) ?: return super.getChangePayload(oldItem, newItem)
    
    38
    +    }
    
    39
    +}
    
    40
    +
    
    41
    +
    
    42
    +
    
    43
    +class TorBootstrapAdapter(
    
    44
    +    private val interactor: TorBootstrapInteractor,
    
    45
    +    private val viewLifecycleOwner: LifecycleOwner,
    
    46
    +    private val components: Components,
    
    47
    +) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) {
    
    48
    +
    
    49
    +    // This method triggers the ComplexMethod lint error when in fact it's quite simple.
    
    50
    +    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    
    51
    +        val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
    
    52
    +        return when (viewType) {
    
    53
    +            TorBootstrapPagerViewHolder.LAYOUT_ID -> TorBootstrapPagerViewHolder(
    
    54
    +                view,
    
    55
    +                components,
    
    56
    +                interactor
    
    57
    +            )
    
    58
    +            else -> throw IllegalStateException()
    
    59
    +        }
    
    60
    +    }
    
    61
    +
    
    62
    +    override fun getItemViewType(position: Int) = getItem(position).viewType
    
    63
    +
    
    64
    +    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) {
    
    65
    +        if (payloads.isEmpty()) {
    
    66
    +            onBindViewHolder(holder, position)
    
    67
    +        } else {
    
    68
    +            when (holder) {
    
    69
    +                is TopSitePagerViewHolder -> {
    
    70
    +                    if (payloads[0] is org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload) {
    
    71
    +                        val payload = payloads[0] as org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload
    
    72
    +                        holder.update(payload)
    
    73
    +                    }
    
    74
    +                }
    
    75
    +            }
    
    76
    +        }
    
    77
    +    }
    
    78
    +
    
    79
    +    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    
    80
    +        // no-op. This ViewHolder receives the HomeStore as argument and will observe that
    
    81
    +        // without the need for us to manually update from here the data to be displayed.
    
    82
    +    }
    
    83
    +}

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapConnectViewHolder.ktfenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt
    ... ... @@ -2,17 +2,16 @@
    2 2
      * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3 3
      * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4 4
     
    
    5
    -package org.mozilla.fenix.home.sessioncontrol.viewholders
    
    5
    +package org.mozilla.fenix.tor.view
    
    6 6
     
    
    7 7
     import android.view.View
    
    8
    -import androidx.appcompat.widget.SwitchCompat
    
    9 8
     import androidx.recyclerview.widget.RecyclerView
    
    10 9
     import org.mozilla.fenix.R
    
    10
    +import org.mozilla.fenix.components.Components
    
    11 11
     import org.mozilla.fenix.databinding.TorBootstrapConnectBinding
    
    12 12
     import org.mozilla.fenix.tor.TorEvents
    
    13 13
     import org.mozilla.fenix.tor.bootstrap.TorQuickStart
    
    14
    -import org.mozilla.fenix.components.Components
    
    15
    -import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
    
    14
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    16 15
     
    
    17 16
     class TorBootstrapConnectViewHolder(
    
    18 17
         private val view: View,
    

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapLoggerViewHolder.ktfenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapLoggerViewHolder.kt
    ... ... @@ -2,20 +2,20 @@
    2 2
      * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3 3
      * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4 4
     
    
    5
    -package org.mozilla.fenix.home.sessioncontrol.viewholders
    
    5
    +package org.mozilla.fenix.tor.view
    
    6 6
     
    
    7 7
     import android.text.method.ScrollingMovementMethod
    
    8 8
     import android.view.View
    
    9 9
     import androidx.recyclerview.widget.RecyclerView
    
    10 10
     import org.mozilla.fenix.R
    
    11
    +import org.mozilla.fenix.components.Components
    
    11 12
     import org.mozilla.fenix.databinding.TorBootstrapLoggerBinding
    
    12 13
     import org.mozilla.fenix.tor.TorEvents
    
    13
    -import org.mozilla.fenix.components.Components
    
    14 14
     
    
    15 15
     class TorBootstrapLoggerViewHolder(
    
    16
    -    private val view: View,
    
    17
    -    private val components: Components
    
    18
    -) : RecyclerView.ViewHolder(view), TorEvents {
    
    16
    +        private val view: View,
    
    17
    +        private val components: Components
    
    18
    +    ) : RecyclerView.ViewHolder(view), TorEvents {
    
    19 19
     
    
    20 20
         private var entries = mutableListOf<String>()
    
    21 21
         private var binding: TorBootstrapLoggerBinding
    
    ... ... @@ -25,10 +25,10 @@ class TorBootstrapLoggerViewHolder(
    25 25
             components.torController.registerTorListener(this)
    
    26 26
     
    
    27 27
             val currentEntries = components.torController.logEntries
    
    28
    -                .filter { it.first != null }
    
    29
    -                .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
    
    30
    -                // Keep synchronized with format in onTorStatusUpdate
    
    31
    -                .flatMap { listOf("(${it.second}) '${it.first}'") }
    
    28
    +            .filter { it.first != null }
    
    29
    +            .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
    
    30
    +            // Keep synchronized with format in onTorStatusUpdate
    
    31
    +            .flatMap { listOf("(${it.second}) '${it.first}'") }
    
    32 32
             val entriesLen = currentEntries.size
    
    33 33
             val subListOffset = if (entriesLen > MAX_NEW_ENTRIES) MAX_NEW_ENTRIES else entriesLen
    
    34 34
             entries = currentEntries.subList((entriesLen - subListOffset), entriesLen) as MutableList<String>
    
    ... ... @@ -72,4 +72,5 @@ class TorBootstrapLoggerViewHolder(
    72 72
             const val MAX_NEW_ENTRIES = 24
    
    73 73
             const val MAX_LINES = 25
    
    74 74
         }
    
    75
    +
    
    75 76
     }

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/torbootstrap/BootstrapPagerAdapter.ktfenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerAdapter.kt
    ... ... @@ -2,18 +2,15 @@
    2 2
      * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3 3
      * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4 4
     
    
    5
    -package org.mozilla.fenix.home.sessioncontrol.viewholders.torbootstrap
    
    5
    +package org.mozilla.fenix.tor.view
    
    6 6
     
    
    7 7
     import android.view.LayoutInflater
    
    8 8
     import android.view.ViewGroup
    
    9 9
     import androidx.recyclerview.widget.RecyclerView
    
    10
    -import androidx.recyclerview.widget.RecyclerView.ViewHolder
    
    11 10
     import org.mozilla.fenix.components.Components
    
    12
    -import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
    
    13
    -import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapConnectViewHolder
    
    14
    -import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapLoggerViewHolder
    
    11
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    15 12
     
    
    16
    -class BootstrapPagerAdapter(
    
    13
    +class TorBootstrapPagerAdapter(
    
    17 14
         private val components: Components,
    
    18 15
         private val interactor: TorBootstrapInteractor
    
    19 16
     ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    

  • fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapPagerViewHolder.ktfenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerViewHolder.kt
    ... ... @@ -2,23 +2,22 @@
    2 2
      * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3 3
      * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4 4
     
    
    5
    -package org.mozilla.fenix.home.sessioncontrol.viewholders
    
    5
    +package org.mozilla.fenix.tor.view
    
    6 6
     
    
    7 7
     import android.view.View
    
    8 8
     import androidx.recyclerview.widget.RecyclerView
    
    9 9
     import org.mozilla.fenix.R
    
    10
    -import org.mozilla.fenix.databinding.TorBootstrapPagerBinding
    
    11 10
     import org.mozilla.fenix.components.Components
    
    12
    -import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
    
    13
    -import org.mozilla.fenix.home.sessioncontrol.viewholders.torbootstrap.BootstrapPagerAdapter
    
    11
    +import org.mozilla.fenix.databinding.TorBootstrapPagerBinding
    
    12
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    14 13
     
    
    15 14
     class TorBootstrapPagerViewHolder(
    
    16
    -    view: View,
    
    17
    -    components: Components,
    
    18
    -    interactor: TorBootstrapInteractor
    
    19
    -) : RecyclerView.ViewHolder(view) {
    
    15
    +        view: View,
    
    16
    +        components: Components,
    
    17
    +        interactor: TorBootstrapInteractor
    
    18
    +    ) : RecyclerView.ViewHolder(view) {
    
    20 19
     
    
    21
    -    private val bootstrapPagerAdapter = BootstrapPagerAdapter(components, interactor)
    
    20
    +    private val bootstrapPagerAdapter = TorBootstrapPagerAdapter(components, interactor)
    
    22 21
     
    
    23 22
         init {
    
    24 23
             val binding = TorBootstrapPagerBinding.bind(view)
    

  • fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapView.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.tor.view
    
    6
    +
    
    7
    +import androidx.lifecycle.LifecycleOwner
    
    8
    +import androidx.recyclerview.widget.LinearLayoutManager
    
    9
    +import androidx.recyclerview.widget.RecyclerView
    
    10
    +import org.mozilla.fenix.components.appstate.AppState
    
    11
    +import org.mozilla.fenix.ext.components
    
    12
    +import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
    
    13
    +
    
    14
    +
    
    15
    +class TorBootstrapView(
    
    16
    +    containerView: RecyclerView,
    
    17
    +    viewLifecycleOwner: LifecycleOwner,
    
    18
    +    interactor: TorBootstrapInteractor,
    
    19
    +) {
    
    20
    +
    
    21
    +    val view: RecyclerView = containerView //as RecyclerView
    
    22
    +
    
    23
    +    private fun bootstrapAdapterItems() = listOf(AdapterItem.TorBootstrap)
    
    24
    +
    
    25
    +    private val torBootstrapAdapter = TorBootstrapAdapter(
    
    26
    +        interactor,
    
    27
    +        viewLifecycleOwner,
    
    28
    +        containerView.context.components,
    
    29
    +    )
    
    30
    +
    
    31
    +    //private val torBootstrapAdapter =
    
    32
    +    //    TorBootstrapAdapter(interactor, containerView.context.components)
    
    33
    +    //private val torBootstrapAdapter = TorBootstrapPagerAdapter(containerView.context.components, interactor)
    
    34
    +
    
    35
    +    init {
    
    36
    +        containerView.apply {
    
    37
    +            adapter = torBootstrapAdapter
    
    38
    +            layoutManager = LinearLayoutManager(containerView.context)
    
    39
    +        }
    
    40
    +    }
    
    41
    +
    
    42
    +    private fun AppState.toAdapterList(): List<AdapterItem> {
    
    43
    +        return bootstrapAdapterItems()
    
    44
    +    }
    
    45
    +
    
    46
    +    fun update(state: AppState) {
    
    47
    +        torBootstrapAdapter.submitList(state.toAdapterList())
    
    48
    +    }
    
    49
    +}

  • fenix/app/src/main/res/drawable/tor_onboarding_donate_gradient.xml deleted
    1
    -<?xml version="1.0" encoding="utf-8"?>
    
    2
    -<!-- This Source Code Form is subject to the terms of the Mozilla Public
    
    3
    -   - License, v. 2.0. If a copy of the MPL was not distributed with this
    
    4
    -   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
    
    5
    -<selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    6
    -    <item>
    
    7
    -        <shape>
    
    8
    -            <gradient
    
    9
    -                    android:angle="45"
    
    10
    -                    android:startColor="#07d1db"
    
    11
    -                    android:endColor="#b240f5"
    
    12
    -                    android:type="linear" />
    
    13
    -        </shape>
    
    14
    -    </item>
    
    15
    -</selector>

  • fenix/app/src/main/res/drawable/tor_onboarding_donate_rounded_corners.xml deleted
    1
    -<?xml version="1.0" encoding="utf-8"?>
    
    2
    -<!-- This Source Code Form is subject to the terms of the Mozilla Public
    
    3
    -   - License, v. 2.0. If a copy of the MPL was not distributed with this
    
    4
    -   - file, You can obtain one at http://mozilla.org/MPL/2.0/.  -->
    
    5
    -
    
    6
    -<!-- Used for rounding the corners of a button -->
    
    7
    -<shape xmlns:android="http://schemas.android.com/apk/res/android"
    
    8
    -       android:shape="rectangle">
    
    9
    -    <solid android:color="#70efde" />
    
    10
    -    <corners android:radius="10dp" />
    
    11
    -</shape>

  • fenix/app/src/main/res/layout/tor_onboarding_donate.xml deleted
    1
    -<?xml version="1.0" encoding="utf-8"?>
    
    2
    -<!-- This Source Code Form is subject to the terms of the Mozilla Public
    
    3
    -   - License, v. 2.0. If a copy of the MPL was not distributed with this
    
    4
    -   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
    
    5
    -<androidx.constraintlayout.widget.ConstraintLayout
    
    6
    -        xmlns:android="http://schemas.android.com/apk/res/android"
    
    7
    -        xmlns:app="http://schemas.android.com/apk/res-auto"
    
    8
    -        xmlns:tools="http://schemas.android.com/tools"
    
    9
    -        android:id="@+id/onboarding_card"
    
    10
    -        style="@style/TorOnboardingDonateCardLightWithPadding"
    
    11
    -        android:layout_width="match_parent"
    
    12
    -        android:layout_height="wrap_content">
    
    13
    -    <TextView
    
    14
    -        android:id="@+id/header_text"
    
    15
    -        android:layout_width="0dp"
    
    16
    -        android:layout_height="wrap_content"
    
    17
    -        android:text="@string/tor_onboarding_donate_header"
    
    18
    -        android:textAppearance="@style/TorHeaderTextStyle"
    
    19
    -        android:gravity="center_vertical"
    
    20
    -        android:lines="1"
    
    21
    -        app:layout_constraintStart_toStartOf="parent"
    
    22
    -        app:layout_constraintTop_toTopOf="parent"
    
    23
    -        app:layout_constraintEnd_toEndOf="parent" />
    
    24
    -    <TextView
    
    25
    -        android:id="@+id/description_text"
    
    26
    -        android:layout_width="match_parent"
    
    27
    -        android:layout_height="wrap_content"
    
    28
    -        android:textAppearance="@style/TorBody16TextStyle"
    
    29
    -        android:layout_marginTop="14dp"
    
    30
    -        android:text="@string/tor_onboarding_donate_description"
    
    31
    -        app:layout_constraintTop_toBottomOf="@id/header_text"
    
    32
    -        app:layout_constraintStart_toStartOf="parent"
    
    33
    -        app:layout_constraintEnd_toEndOf="parent" />
    
    34
    -
    
    35
    -    <Button
    
    36
    -        style="@style/TorDonateOnboardingButton"
    
    37
    -        android:id="@+id/donate_now_button"
    
    38
    -        android:text="@string/tor_onboarding_donate_button"
    
    39
    -        android:layout_marginTop="10dp"
    
    40
    -        android:textAppearance="@style/TorHeaderTextStyle"
    
    41
    -        android:background="@drawable/tor_onboarding_donate_rounded_corners"
    
    42
    -        app:layout_constraintTop_toBottomOf="@id/description_text"
    
    43
    -        app:layout_constraintStart_toStartOf="parent"
    
    44
    -        app:layout_constraintEnd_toEndOf="parent"
    
    45
    -        app:layout_constraintBottom_toBottomOf="parent"/>
    
    46
    -</androidx.constraintlayout.widget.ConstraintLayout>

  • fenix/app/src/main/res/layout/tor_onboarding_security_level.xml deleted
    1
    -<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    -   - License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    -   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
    
    4
    -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    
    5
    -    xmlns:app="http://schemas.android.com/apk/res-auto"
    
    6
    -    xmlns:tools="http://schemas.android.com/tools"
    
    7
    -    android:id="@+id/onboarding_card"
    
    8
    -    style="@style/OnboardingCardLightWithPadding"
    
    9
    -    android:layout_width="match_parent"
    
    10
    -    android:layout_height="wrap_content"
    
    11
    -    android:clipChildren="false"
    
    12
    -    android:clipToPadding="false">
    
    13
    -
    
    14
    -    <TextView
    
    15
    -        android:id="@+id/header_text"
    
    16
    -        android:layout_width="0dp"
    
    17
    -        android:layout_height="wrap_content"
    
    18
    -        android:drawablePadding="12dp"
    
    19
    -        android:gravity="center_vertical"
    
    20
    -        android:lines="1"
    
    21
    -        android:text="@string/tor_onboarding_security_level"
    
    22
    -        android:textAppearance="@style/HeaderTextStyle"
    
    23
    -        app:layout_constraintStart_toStartOf="parent"
    
    24
    -        app:layout_constraintTop_toTopOf="parent"
    
    25
    -        tools:drawableStart="@drawable/ic_onboarding_tracking_protection" />
    
    26
    -
    
    27
    -    <TextView
    
    28
    -        android:id="@+id/description_text"
    
    29
    -        android:layout_width="match_parent"
    
    30
    -        android:layout_height="wrap_content"
    
    31
    -        android:layout_marginTop="12dp"
    
    32
    -        android:textAppearance="@style/Body14TextStyle"
    
    33
    -        app:layout_constraintEnd_toEndOf="parent"
    
    34
    -        app:layout_constraintStart_toStartOf="parent"
    
    35
    -        app:layout_constraintTop_toBottomOf="@id/current_level"
    
    36
    -        tools:text="@string/tor_onboarding_security_level_description" />
    
    37
    -
    
    38
    -    <TextView
    
    39
    -        android:id="@+id/current_level"
    
    40
    -        android:layout_width="match_parent"
    
    41
    -        android:layout_height="wrap_content"
    
    42
    -        android:layout_marginTop="12dp"
    
    43
    -        app:layout_constraintEnd_toEndOf="parent"
    
    44
    -        app:layout_constraintStart_toStartOf="parent"
    
    45
    -        app:layout_constraintTop_toBottomOf="@id/header_text"
    
    46
    -        tools:text="@string/tor_onboarding_chosen_security_level_label" />
    
    47
    -
    
    48
    -    <org.mozilla.fenix.onboarding.OnboardingRadioButton
    
    49
    -        android:id="@+id/security_level_standard_option"
    
    50
    -        android:layout_width="match_parent"
    
    51
    -        android:layout_height="wrap_content"
    
    52
    -        android:layout_marginStart="16dp"
    
    53
    -        android:layout_marginTop="16dp"
    
    54
    -        android:layout_marginBottom="16dp"
    
    55
    -        android:background="@android:color/transparent"
    
    56
    -        android:checked="true"
    
    57
    -        android:foreground="@drawable/rounded_ripple"
    
    58
    -        android:gravity="top"
    
    59
    -        android:paddingStart="8dp"
    
    60
    -        android:paddingEnd="8dp"
    
    61
    -        android:theme="@style/Checkable.Colored"
    
    62
    -        app:layout_constraintStart_toStartOf="parent"
    
    63
    -        app:layout_constraintTop_toBottomOf="@id/description_text"
    
    64
    -        app:onboardingKey="@string/pref_key_tor_security_level_standard_option"
    
    65
    -        app:onboardingKeyDescription="@string/tor_security_level_standard_description"
    
    66
    -        app:onboardingKeyTitle="@string/tor_security_level_standard_option"
    
    67
    -        tools:text="Standard" />
    
    68
    -
    
    69
    -    <org.mozilla.fenix.onboarding.OnboardingRadioButton
    
    70
    -        android:id="@+id/security_level_safer_option"
    
    71
    -        android:layout_width="match_parent"
    
    72
    -        android:layout_height="wrap_content"
    
    73
    -        android:layout_marginStart="16dp"
    
    74
    -        android:layout_marginTop="16dp"
    
    75
    -        android:layout_marginBottom="16dp"
    
    76
    -        android:background="@android:color/transparent"
    
    77
    -        android:checked="false"
    
    78
    -        android:foreground="@drawable/rounded_ripple"
    
    79
    -        android:gravity="top"
    
    80
    -        android:paddingStart="8dp"
    
    81
    -        android:paddingEnd="8dp"
    
    82
    -        android:textColor="@color/primary_state_list_text_color"
    
    83
    -        android:theme="@style/Checkable.Colored"
    
    84
    -        app:layout_constraintStart_toStartOf="parent"
    
    85
    -        app:layout_constraintTop_toBottomOf="@id/security_level_standard_option"
    
    86
    -        app:onboardingKey="@string/pref_key_tor_security_level_safer_option"
    
    87
    -        app:onboardingKeyDescription="@string/tor_security_level_safer_description"
    
    88
    -        app:onboardingKeyTitle="@string/tor_security_level_safer_option"
    
    89
    -        tools:text="Safer" />
    
    90
    -
    
    91
    -    <org.mozilla.fenix.onboarding.OnboardingRadioButton
    
    92
    -        android:id="@+id/security_level_safest_option"
    
    93
    -        android:layout_width="match_parent"
    
    94
    -        android:layout_height="wrap_content"
    
    95
    -        android:layout_marginStart="16dp"
    
    96
    -        android:layout_marginTop="16dp"
    
    97
    -        android:layout_marginBottom="16dp"
    
    98
    -        android:background="@android:color/transparent"
    
    99
    -        android:checked="false"
    
    100
    -        android:foreground="@drawable/rounded_ripple"
    
    101
    -        android:gravity="top"
    
    102
    -        android:paddingStart="8dp"
    
    103
    -        android:paddingEnd="8dp"
    
    104
    -        android:textColor="@color/primary_state_list_text_color"
    
    105
    -        android:theme="@style/Checkable.Colored"
    
    106
    -        app:layout_constraintStart_toStartOf="parent"
    
    107
    -        app:layout_constraintTop_toBottomOf="@id/security_level_safer_option"
    
    108
    -        app:onboardingKey="@string/pref_key_tor_security_level_safest_option"
    
    109
    -        app:onboardingKeyDescription="@string/tor_security_level_safest_description"
    
    110
    -        app:onboardingKeyTitle="@string/tor_security_level_safest_option"
    
    111
    -        tools:text="Safest" />
    
    112
    -
    
    113
    -    <Button
    
    114
    -        android:id="@+id/open_settings_button"
    
    115
    -        style="@style/NeutralOnboardingButton"
    
    116
    -        android:layout_marginTop="16dp"
    
    117
    -        android:text="@string/tor_onboarding_security_settings_button"
    
    118
    -        app:layout_constraintTop_toBottomOf="@id/security_level_safest_option"
    
    119
    -        app:layout_constraintStart_toStartOf="parent"
    
    120
    -        app:layout_constraintEnd_toEndOf="parent"
    
    121
    -        app:layout_constraintBottom_toBottomOf="parent"/>
    
    122
    -
    
    123
    -</androidx.constraintlayout.widget.ConstraintLayout>

  • fenix/app/src/main/res/navigation/nav_graph.xml
    ... ... @@ -21,6 +21,12 @@
    21 21
             app:popUpTo="@id/startupFragment"
    
    22 22
             app:popUpToInclusive="true" />
    
    23 23
     
    
    24
    +    <action
    
    25
    +        android:id="@+id/action_startup_torbootstrap"
    
    26
    +        app:destination="@id/torbootstrapFragment"
    
    27
    +        app:popUpTo="@id/startupFragment"
    
    28
    +        app:popUpToInclusive="true" />
    
    29
    +
    
    24 30
         <action
    
    25 31
             android:id="@+id/action_global_home"
    
    26 32
             app:destination="@id/homeFragment"
    
    ... ... @@ -247,6 +253,24 @@
    247 253
                 app:popUpToInclusive="true" />
    
    248 254
         </fragment>
    
    249 255
     
    
    256
    +    <fragment
    
    257
    +        android:id="@+id/torbootstrapFragment"
    
    258
    +        android:name="org.mozilla.fenix.tor.TorBootstrapFragment"
    
    259
    +        tools:layout="@layout/fragment_home">
    
    260
    +        <action
    
    261
    +            android:id="@+id/action_home"
    
    262
    +            app:destination="@id/homeFragment"
    
    263
    +            app:popUpTo="@id/torbootstrapFragment"
    
    264
    +            app:popUpToInclusive="true" />
    
    265
    +        <action
    
    266
    +            android:id="@+id/action_torbootstrapFragment_to_torNetworkSettingsFragment"
    
    267
    +            app:destination="@id/torNetworkSettingsFragment"
    
    268
    +            app:enterAnim="@anim/slide_in_right"
    
    269
    +            app:exitAnim="@anim/slide_out_left"
    
    270
    +            app:popEnterAnim="@anim/slide_in_left"
    
    271
    +            app:popExitAnim="@anim/slide_out_right" />
    
    272
    +    </fragment>
    
    273
    +
    
    250 274
         <dialog
    
    251 275
             android:id="@+id/homeOnboardingDialogFragment"
    
    252 276
             android:name="org.mozilla.fenix.onboarding.HomeOnboardingDialogFragment" />
    

  • fenix/app/src/main/res/values/styles.xml
    ... ... @@ -375,13 +375,6 @@
    375 375
             <item name="android:textColor">?attr/textPrimary</item>
    
    376 376
         </style>
    
    377 377
     
    
    378
    -    <!-- Ideally we should consolidate this with NeutralButton in the future -->
    
    379
    -    <style name="TorDonateOnboardingButton" parent="NeutralButton">
    
    380
    -        <item name="android:background">@drawable/tor_onboarding_donate_rounded_corners</item>
    
    381
    -        <item name="backgroundTint">#70efde</item>
    
    382
    -        <item name="android:textColor">#000000</item>
    
    383
    -    </style>
    
    384
    -
    
    385 378
         <style name="DestructiveButton" parent="NeutralButton">
    
    386 379
             <item name="iconTint">@color/fx_mobile_icon_color_warning_button</item>
    
    387 380
             <item name="android:textColor">@color/fx_mobile_text_color_warning_button</item>
    
    ... ... @@ -582,10 +575,6 @@
    582 575
             <item name="android:elevation">0dp</item>
    
    583 576
         </style>
    
    584 577
     
    
    585
    -    <style name="TorOnboardingDonateCardLightWithPadding" parent="OnboardingCardDark">
    
    586
    -        <item name="android:background">@drawable/tor_onboarding_donate_gradient</item>
    
    587
    -    </style>
    
    588
    -
    
    589 578
         <style name="SearchClipboardStyle">
    
    590 579
             <item name="android:ellipsize">end</item>
    
    591 580
             <item name="android:maxLines">1</item>