Dan Ballard pushed to branch firefox-android-115.2.1-13.0-1 at The Tor Project / Applications / firefox-android
Commits:
-
a09967fd
by Dan Ballard at 2023-09-12T08:52:55-07:00
-
40bf5511
by Dan Ballard at 2023-09-12T08:52:55-07:00
-
d2a7dfa6
by Dan Ballard at 2023-09-12T08:52:55-07:00
25 changed files:
- fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/Mode.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
- − fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingDonateViewHolder.kt
- − fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/controller/TorBootstrapController.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/interactor/TorBootstrapInteractor.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapAdapter.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapConnectViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapLoggerViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapLoggerViewHolder.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/torbootstrap/BootstrapPagerAdapter.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerAdapter.kt
- fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapPagerViewHolder.kt → fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerViewHolder.kt
- + fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapView.kt
- − fenix/app/src/main/res/drawable/tor_onboarding_donate_gradient.xml
- − fenix/app/src/main/res/drawable/tor_onboarding_donate_rounded_corners.xml
- − fenix/app/src/main/res/layout/tor_onboarding_donate.xml
- − fenix/app/src/main/res/layout/tor_onboarding_security_level.xml
- fenix/app/src/main/res/navigation/nav_graph.xml
- fenix/app/src/main/res/values/styles.xml
Changes:
... | ... | @@ -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) {
|
... | ... | @@ -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 | } |
... | ... | @@ -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 | -} |
... | ... | @@ -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 | }
|
... | ... | @@ -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 | } |
... | ... | @@ -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 | } |
... | ... | @@ -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) =
|
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 | -} |
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 | -} |
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 | +} |
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 | +} |
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 | +} |
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 | +} |
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 | +} |
... | ... | @@ -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,
|
... | ... | @@ -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 | } |
... | ... | @@ -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>() {
|
... | ... | @@ -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)
|
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 | +} |
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> |
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> |
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> |
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> |
... | ... | @@ -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" />
|
... | ... | @@ -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>
|