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>
|