Commits:
-
a09967fd
by Dan Ballard at 2023-09-12T08:52:55-07:00
fixup! Add Tor integration and UI
Bug 41878: Remove bootstrap from `Add Tor integration and UI`
-
40bf5511
by Dan Ballard at 2023-09-12T08:52:55-07:00
fixup! Add Tor integration and UI
Bug 41878: Remove rest of onboarding from `Add Tor integration and UI`
-
d2a7dfa6
by Dan Ballard at 2023-09-12T08:52:55-07:00
Bug 41878: Add standalone Tor Bootstrap
25 changed files:
Changes:
fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
... |
... |
@@ -34,6 +34,7 @@ import androidx.annotation.VisibleForTesting.Companion.PROTECTED |
34
|
34
|
import androidx.appcompat.app.ActionBar
|
35
|
35
|
import androidx.appcompat.widget.Toolbar
|
36
|
36
|
import androidx.core.app.NotificationManagerCompat
|
|
37
|
+import androidx.core.content.ContentProviderCompat.requireContext
|
37
|
38
|
import androidx.lifecycle.lifecycleScope
|
38
|
39
|
import androidx.navigation.NavDestination
|
39
|
40
|
import androidx.navigation.NavDirections
|
... |
... |
@@ -285,6 +286,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { |
285
|
286
|
it.start()
|
286
|
287
|
}
|
287
|
288
|
|
|
289
|
+ /*
|
288
|
290
|
if (settings().shouldShowJunoOnboarding(
|
289
|
291
|
hasUserBeenOnboarded = components.fenixOnboarding.userHasBeenOnboarded(),
|
290
|
292
|
isLauncherIntent = intent.toSafeIntent().isLauncherIntent,
|
... |
... |
@@ -295,6 +297,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { |
295
|
297
|
navHost.navController.navigate(NavGraphDirections.actionGlobalJunoOnboarding())
|
296
|
298
|
}
|
297
|
299
|
} else {
|
|
300
|
+ */
|
298
|
301
|
lifecycleScope.launch(IO) {
|
299
|
302
|
// showFullscreenMessageIfNeeded(applicationContext)
|
300
|
303
|
}
|
... |
... |
@@ -315,7 +318,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { |
315
|
318
|
}
|
316
|
319
|
showNotificationPermissionPromptIfRequired()
|
317
|
320
|
*/
|
318
|
|
- }
|
|
321
|
+ //}
|
319
|
322
|
|
320
|
323
|
Performance.processIntentIfPerformanceTest(intent, this)
|
321
|
324
|
|
... |
... |
@@ -1158,13 +1161,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { |
1158
|
1161
|
}
|
1159
|
1162
|
|
1160
|
1163
|
open fun navigateToHome() {
|
1161
|
|
- // if (components.fenixOnboarding.userHasBeenOnboarded()) {
|
1162
|
|
- navHost.navController.navigate(NavGraphDirections.actionStartupHome())
|
1163
|
|
- /*
|
1164
|
|
- } else {
|
1165
|
|
- navHost.navController.navigate(NavGraphDirections.actionStartupOnboarding())
|
1166
|
|
- }
|
1167
|
|
- */
|
|
1164
|
+ navHost.navController.navigate(NavGraphDirections.actionStartupTorbootstrap())
|
1168
|
1165
|
}
|
1169
|
1166
|
|
1170
|
1167
|
override fun attachBaseContext(base: Context) {
|
fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
... |
... |
@@ -113,6 +113,8 @@ import org.mozilla.fenix.perf.runBlockingIncrement |
113
|
113
|
import org.mozilla.fenix.search.toolbar.DefaultSearchSelectorController
|
114
|
114
|
import org.mozilla.fenix.search.toolbar.SearchSelectorMenu
|
115
|
115
|
import org.mozilla.fenix.tabstray.TabsTrayAccessPoint
|
|
116
|
+import org.mozilla.fenix.tor.TorBootstrapFragmentDirections
|
|
117
|
+import org.mozilla.fenix.tor.TorBootstrapStatus
|
116
|
118
|
import org.mozilla.fenix.tor.bootstrap.TorQuickStart
|
117
|
119
|
import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
|
118
|
120
|
import org.mozilla.fenix.utils.allowUndo
|
... |
... |
@@ -200,9 +202,9 @@ class HomeFragment : Fragment() { |
200
|
202
|
private val recentBookmarksFeature = ViewBoundFeatureWrapper<RecentBookmarksFeature>()
|
201
|
203
|
private val historyMetadataFeature = ViewBoundFeatureWrapper<RecentVisitsFeature>()
|
202
|
204
|
private val searchSelectorBinding = ViewBoundFeatureWrapper<SearchSelectorBinding>()
|
203
|
|
- private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
|
204
|
205
|
private val torQuickStart by lazy { TorQuickStart(requireContext()) }
|
205
|
|
- private lateinit var currentMode: CurrentMode
|
|
206
|
+ private val searchSelectorMenuBinding = ViewBoundFeatureWrapper<SearchSelectorMenuBinding>()
|
|
207
|
+ private lateinit var torBootstrapStatus: TorBootstrapStatus
|
206
|
208
|
|
207
|
209
|
override fun onCreate(savedInstanceState: Bundle?) {
|
208
|
210
|
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
|
... |
... |
@@ -233,29 +235,27 @@ class HomeFragment : Fragment() { |
233
|
235
|
val activity = activity as HomeActivity
|
234
|
236
|
val components = requireComponents
|
235
|
237
|
|
236
|
|
- val currentWallpaperName = requireContext().settings().currentWallpaperName
|
237
|
|
- applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false)
|
238
|
|
-
|
239
|
|
- currentMode = CurrentMode(
|
240
|
|
- requireContext(),
|
|
238
|
+ torBootstrapStatus = TorBootstrapStatus(
|
241
|
239
|
torQuickStart,
|
242
|
240
|
!BuildConfig.DISABLE_TOR,
|
243
|
241
|
components.torController,
|
244
|
|
- browsingModeManager,
|
245
|
242
|
::dispatchModeChanges
|
246
|
243
|
)
|
247
|
244
|
|
|
245
|
+ val currentWallpaperName = requireContext().settings().currentWallpaperName
|
|
246
|
+ applyWallpaper(wallpaperName = currentWallpaperName, orientationChange = false)
|
|
247
|
+
|
248
|
248
|
// Splits by full stops or commas and puts the parts in different lines.
|
249
|
249
|
// Ignoring separators at the end of the string, it is expected
|
250
|
250
|
// that there are at most two parts (e.g. "Explore. Privately.").
|
251
|
|
- val localBinding = binding;
|
|
251
|
+ val localBinding = binding
|
252
|
252
|
binding.exploreprivately.text = localBinding
|
253
|
253
|
.exploreprivately
|
254
|
254
|
.text
|
255
|
255
|
?.replace(" *([.,。।]) *".toRegex(), "$1\n")
|
256
|
256
|
?.trim()
|
257
|
257
|
|
258
|
|
- components.appStore.dispatch(AppAction.ModeChange(currentMode.getCurrentMode()))
|
|
258
|
+ components.appStore.dispatch(AppAction.ModeChange(Mode.fromBrowsingMode(browsingModeManager.mode)))
|
259
|
259
|
|
260
|
260
|
lifecycleScope.launch(IO) {
|
261
|
261
|
if (requireContext().settings().showPocketRecommendationsFeature) {
|
... |
... |
@@ -378,10 +378,6 @@ class HomeFragment : Fragment() { |
378
|
378
|
registerCollectionStorageObserver = ::registerCollectionStorageObserver,
|
379
|
379
|
removeCollectionWithUndo = ::removeCollectionWithUndo,
|
380
|
380
|
showTabTray = ::openTabsTray,
|
381
|
|
- handleTorBootstrapConnect = ::handleTorBootstrapConnect,
|
382
|
|
- cancelTorBootstrap = ::cancelTorBootstrap,
|
383
|
|
- initiateTorBootstrap = ::initiateTorBootstrap,
|
384
|
|
- openTorNetworkSettings = ::openTorNetworkSettings
|
385
|
381
|
),
|
386
|
382
|
recentTabController = DefaultRecentTabsController(
|
387
|
383
|
selectTabUseCase = components.useCases.tabsUseCases.selectTab,
|
... |
... |
@@ -447,9 +443,6 @@ class HomeFragment : Fragment() { |
447
|
443
|
|
448
|
444
|
FxNimbus.features.homescreen.recordExposure()
|
449
|
445
|
|
450
|
|
- adjustHomeFragmentView(currentMode.getCurrentMode())
|
451
|
|
- showSessionControlView()
|
452
|
|
-
|
453
|
446
|
// DO NOT MOVE ANYTHING BELOW THIS addMarker CALL!
|
454
|
447
|
requireComponents.core.engine.profiler?.addMarker(
|
455
|
448
|
MarkersFragmentLifecycleCallbacks.MARKER_NAME,
|
... |
... |
@@ -530,111 +523,6 @@ class HomeFragment : Fragment() { |
530
|
523
|
binding.homeAppBar.setExpanded(true)
|
531
|
524
|
}
|
532
|
525
|
|
533
|
|
- // This function should be paired with showSessionControlView()
|
534
|
|
- @SuppressWarnings("ComplexMethod", "NestedBlockDepth", "LongMethod")
|
535
|
|
- private fun adjustHomeFragmentView(mode: Mode) {
|
536
|
|
- binding.sessionControlRecyclerView.apply {
|
537
|
|
- visibility = View.INVISIBLE
|
538
|
|
- }
|
539
|
|
-
|
540
|
|
- if (mode == Mode.Bootstrap) {
|
541
|
|
- binding.sessionControlRecyclerView.apply {
|
542
|
|
- setPadding(0, 0, 0, 0)
|
543
|
|
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(0, 0, 0, 0)
|
544
|
|
- }
|
545
|
|
- binding.homeAppBar.apply {
|
546
|
|
- visibility = View.GONE
|
547
|
|
-
|
548
|
|
- // Reset this as SCROLL in case it was previously set as NO_SCROLL after bootstrap
|
549
|
|
- children.forEach {
|
550
|
|
- (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
|
551
|
|
- AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
|
552
|
|
- }
|
553
|
|
- }
|
554
|
|
- binding.onionPatternImage.apply {
|
555
|
|
- visibility = View.GONE
|
556
|
|
- }
|
557
|
|
- binding.toolbarLayout.apply {
|
558
|
|
- visibility = View.GONE
|
559
|
|
- }
|
560
|
|
- } else {
|
561
|
|
- // Keep synchronized with xml layout (somehow).
|
562
|
|
- binding.sessionControlRecyclerView.apply {
|
563
|
|
- setPadding(
|
564
|
|
- SESSION_CONTROL_VIEW_PADDING,
|
565
|
|
- SESSION_CONTROL_VIEW_PADDING,
|
566
|
|
- SESSION_CONTROL_VIEW_PADDING,
|
567
|
|
- SESSION_CONTROL_VIEW_PADDING
|
568
|
|
- )
|
569
|
|
- // Default margin until it is re-set below (either set immediately or after Layout)
|
570
|
|
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
|
571
|
|
- 0,
|
572
|
|
- 0,
|
573
|
|
- 0,
|
574
|
|
- DEFAULT_ONBOARDING_FINISH_MARGIN
|
575
|
|
- )
|
576
|
|
- }
|
577
|
|
- binding.toolbarLayout.apply {
|
578
|
|
- visibility = View.VISIBLE
|
579
|
|
- // If the Layout rendering pass was completed, then we have a |height| value,
|
580
|
|
- // if it wasn't completed then we have 0.
|
581
|
|
- if (height == 0) {
|
582
|
|
- // Set the bottom margin after the toolbar height is defined during Layout
|
583
|
|
- doOnLayout {
|
584
|
|
- val toolbarLayoutHeight = binding.toolbarLayout.height
|
585
|
|
- binding.sessionControlRecyclerView.apply {
|
586
|
|
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
|
587
|
|
- 0,
|
588
|
|
- 0,
|
589
|
|
- 0,
|
590
|
|
- toolbarLayoutHeight - SESSION_CONTROL_VIEW_PADDING
|
591
|
|
- )
|
592
|
|
- }
|
593
|
|
- }
|
594
|
|
- } else {
|
595
|
|
- binding.sessionControlRecyclerView.apply {
|
596
|
|
- (layoutParams as ViewGroup.MarginLayoutParams).setMargins(
|
597
|
|
- 0,
|
598
|
|
- 0,
|
599
|
|
- 0,
|
600
|
|
- height - SESSION_CONTROL_VIEW_PADDING
|
601
|
|
- )
|
602
|
|
- }
|
603
|
|
- }
|
604
|
|
- }
|
605
|
|
- // Hide the onion pattern during Onboarding, too.
|
606
|
|
- // With new onboarding HomeFragment is only reached once onboarding is complete
|
607
|
|
- binding.onionPatternImage.apply {
|
608
|
|
- visibility = if (currentMode.getCurrentMode() != Mode.Bootstrap) {
|
609
|
|
- View.VISIBLE
|
610
|
|
- } else {
|
611
|
|
- View.GONE
|
612
|
|
- }
|
613
|
|
-
|
614
|
|
- }
|
615
|
|
- binding.homeAppBar.apply {
|
616
|
|
- visibility = View.VISIBLE
|
617
|
|
-
|
618
|
|
- children.forEach {
|
619
|
|
- (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
|
620
|
|
- if (currentMode.getCurrentMode() != Mode.Bootstrap) {
|
621
|
|
- AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
|
622
|
|
- } else {
|
623
|
|
- AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
|
624
|
|
- }
|
625
|
|
-
|
626
|
|
- }
|
627
|
|
- }
|
628
|
|
- }
|
629
|
|
- }
|
630
|
|
-
|
631
|
|
- // This function should be paired with adjustHomeFragmentView()
|
632
|
|
- private fun showSessionControlView() {
|
633
|
|
- binding.sessionControlRecyclerView.apply {
|
634
|
|
- visibility = View.VISIBLE
|
635
|
|
- }
|
636
|
|
- }
|
637
|
|
-
|
638
|
526
|
@Suppress("LongMethod", "ComplexMethod")
|
639
|
527
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
640
|
528
|
// DO NOT ADD ANYTHING ABOVE THIS getProfilerTime CALL!
|
... |
... |
@@ -880,13 +768,14 @@ class HomeFragment : Fragment() { |
880
|
768
|
requireComponents.reviewPromptController.promptReview(requireActivity())
|
881
|
769
|
}
|
882
|
770
|
}
|
883
|
|
-
|
884
|
|
- private fun dispatchModeChanges(mode: Mode) {
|
885
|
|
- requireComponents.appStore.dispatch(AppAction.ModeChange(mode))
|
886
|
771
|
|
887
|
|
- adjustHomeFragmentView(mode)
|
888
|
|
- updateSessionControlView()
|
889
|
|
- showSessionControlView()
|
|
772
|
+ private fun dispatchModeChanges(isBootstrapping: Boolean) {
|
|
773
|
+ if (isBootstrapping) {
|
|
774
|
+ val directions =
|
|
775
|
+ TorBootstrapFragmentDirections
|
|
776
|
+ .actionStartupTorbootstrap()
|
|
777
|
+ findNavController().navigate(directions)
|
|
778
|
+ }
|
890
|
779
|
}
|
891
|
780
|
|
892
|
781
|
@VisibleForTesting
|
... |
... |
@@ -912,21 +801,16 @@ class HomeFragment : Fragment() { |
912
|
801
|
|
913
|
802
|
override fun onStop() {
|
914
|
803
|
super.onStop()
|
915
|
|
- currentMode.unregisterTorListener()
|
|
804
|
+ torBootstrapStatus.unregisterTorListener()
|
916
|
805
|
}
|
917
|
806
|
|
918
|
807
|
override fun onResume() {
|
919
|
808
|
super.onResume()
|
|
809
|
+ torBootstrapStatus.registerTorListener()
|
920
|
810
|
if (browsingModeManager.mode == BrowsingMode.Private) {
|
921
|
811
|
activity?.window?.setBackgroundDrawableResource(R.drawable.private_home_background_gradient)
|
922
|
812
|
}
|
923
|
813
|
|
924
|
|
- // fenix#40176: Ensure the Home fragment is rendered correctly when we resume.
|
925
|
|
- val mode = currentMode.getCurrentMode()
|
926
|
|
- adjustHomeFragmentView(mode)
|
927
|
|
- updateSessionControlView()
|
928
|
|
- showSessionControlView()
|
929
|
|
-
|
930
|
814
|
hideToolbar()
|
931
|
815
|
|
932
|
816
|
// Whenever a tab is selected its last access timestamp is automatically updated by A-C.
|
... |
... |
@@ -1113,25 +997,6 @@ class HomeFragment : Fragment() { |
1113
|
997
|
}
|
1114
|
998
|
}
|
1115
|
999
|
|
1116
|
|
- private fun handleTorBootstrapConnect() {
|
1117
|
|
- requireComponents.torController.onTorConnecting()
|
1118
|
|
- }
|
1119
|
|
-
|
1120
|
|
- private fun cancelTorBootstrap() {
|
1121
|
|
- requireComponents.torController.stopTor()
|
1122
|
|
- }
|
1123
|
|
-
|
1124
|
|
- private fun initiateTorBootstrap(withDebugLogging: Boolean = false) {
|
1125
|
|
- requireComponents.torController.initiateTorBootstrap(lifecycleScope, withDebugLogging)
|
1126
|
|
- }
|
1127
|
|
-
|
1128
|
|
- private fun openTorNetworkSettings() {
|
1129
|
|
- val directions =
|
1130
|
|
- HomeFragmentDirections
|
1131
|
|
- .actionHomeFragmentToTorNetworkSettingsFragment()
|
1132
|
|
- findNavController().navigate(directions)
|
1133
|
|
- }
|
1134
|
|
-
|
1135
|
1000
|
companion object {
|
1136
|
1001
|
const val ALL_NORMAL_TABS = "all_normal"
|
1137
|
1002
|
const val ALL_PRIVATE_TABS = "all_private"
|
... |
... |
@@ -1153,9 +1018,5 @@ class HomeFragment : Fragment() { |
1153
|
1018
|
|
1154
|
1019
|
// Elevation for undo toasts
|
1155
|
1020
|
internal const val TOAST_ELEVATION = 80f
|
1156
|
|
-
|
1157
|
|
- // Layout
|
1158
|
|
- private const val DEFAULT_ONBOARDING_FINISH_MARGIN = 60
|
1159
|
|
- private const val SESSION_CONTROL_VIEW_PADDING = 16
|
1160
|
1021
|
}
|
1161
|
1022
|
} |
fenix/app/src/main/java/org/mozilla/fenix/home/Mode.kt
... |
... |
@@ -4,12 +4,7 @@ |
4
|
4
|
|
5
|
5
|
package org.mozilla.fenix.home
|
6
|
6
|
|
7
|
|
-import android.content.Context
|
8
|
|
-import org.mozilla.fenix.tor.TorController
|
9
|
|
-import org.mozilla.fenix.tor.TorEvents
|
10
|
|
-import org.mozilla.fenix.tor.bootstrap.TorQuickStart
|
11
|
7
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
12
|
|
-import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
13
|
8
|
|
14
|
9
|
/**
|
15
|
10
|
* Describes various states of the home fragment UI.
|
... |
... |
@@ -17,7 +12,6 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager |
17
|
12
|
sealed class Mode {
|
18
|
13
|
object Normal : Mode()
|
19
|
14
|
object Private : Mode()
|
20
|
|
- object Bootstrap : Mode()
|
21
|
15
|
|
22
|
16
|
companion object {
|
23
|
17
|
fun fromBrowsingMode(browsingMode: BrowsingMode) = when (browsingMode) {
|
... |
... |
@@ -26,48 +20,3 @@ sealed class Mode { |
26
|
20
|
}
|
27
|
21
|
}
|
28
|
22
|
} |
29
|
|
-
|
30
|
|
-@SuppressWarnings("LongParameterList", "TooManyFunctions")
|
31
|
|
-class CurrentMode(
|
32
|
|
- private val context: Context,
|
33
|
|
- private val torQuickStart: TorQuickStart,
|
34
|
|
- private val shouldStartTor: Boolean,
|
35
|
|
- private val torController: TorController,
|
36
|
|
- private val browsingModeManager: BrowsingModeManager,
|
37
|
|
- private val dispatchModeChanges: (mode: Mode) -> Unit
|
38
|
|
-) : TorEvents {
|
39
|
|
-
|
40
|
|
- init {
|
41
|
|
- torController.registerTorListener(this)
|
42
|
|
- }
|
43
|
|
-
|
44
|
|
- fun getCurrentMode() = if (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped)) {
|
45
|
|
- Mode.Bootstrap
|
46
|
|
- } else {
|
47
|
|
- Mode.fromBrowsingMode(browsingModeManager.mode)
|
48
|
|
- }
|
49
|
|
-
|
50
|
|
- fun emitModeChanges() {
|
51
|
|
- dispatchModeChanges(getCurrentMode())
|
52
|
|
- }
|
53
|
|
-
|
54
|
|
- @SuppressWarnings("EmptyFunctionBlock")
|
55
|
|
- override fun onTorConnecting() {
|
56
|
|
- }
|
57
|
|
-
|
58
|
|
- override fun onTorConnected() {
|
59
|
|
- dispatchModeChanges(getCurrentMode())
|
60
|
|
- }
|
61
|
|
-
|
62
|
|
- override fun onTorStopped() {
|
63
|
|
- dispatchModeChanges(getCurrentMode())
|
64
|
|
- }
|
65
|
|
-
|
66
|
|
- @SuppressWarnings("EmptyFunctionBlock")
|
67
|
|
- override fun onTorStatusUpdate(entry: String?, status: String?) {
|
68
|
|
- }
|
69
|
|
-
|
70
|
|
- fun unregisterTorListener() {
|
71
|
|
- torController.unregisterTorListener(this)
|
72
|
|
- }
|
73
|
|
-} |
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt
... |
... |
@@ -34,10 +34,7 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHol |
34
|
34
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.CustomizeHomeButtonViewHolder
|
35
|
35
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.NoCollectionsMessageViewHolder
|
36
|
36
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder
|
37
|
|
-import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapPagerViewHolder
|
38
|
37
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.MessageCardViewHolder
|
39
|
|
-import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.TorOnboardingSecurityLevelViewHolder
|
40
|
|
-import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.TorOnboardingDonateViewHolder
|
41
|
38
|
import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
|
42
|
39
|
import mozilla.components.feature.tab.collections.Tab as ComponentTab
|
43
|
40
|
|
... |
... |
@@ -102,8 +99,6 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) { |
102
|
99
|
object PrivateBrowsingDescription : AdapterItem(PrivateBrowsingDescriptionViewHolder.LAYOUT_ID)
|
103
|
100
|
object NoCollectionsMessage : AdapterItem(NoCollectionsMessageViewHolder.LAYOUT_ID)
|
104
|
101
|
|
105
|
|
- object TorBootstrap : AdapterItem(TorBootstrapPagerViewHolder.LAYOUT_ID)
|
106
|
|
-
|
107
|
102
|
object CollectionHeader : AdapterItem(CollectionHeaderViewHolder.LAYOUT_ID)
|
108
|
103
|
data class CollectionItem(
|
109
|
104
|
val collection: TabCollection,
|
... |
... |
@@ -143,9 +138,6 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) { |
143
|
138
|
|
144
|
139
|
object CustomizeHomeButton : AdapterItem(CustomizeHomeButtonViewHolder.LAYOUT_ID)
|
145
|
140
|
|
146
|
|
- object TorOnboardingSecurityLevel : AdapterItem(TorOnboardingSecurityLevelViewHolder.LAYOUT_ID)
|
147
|
|
- object TorOnboardingDonate : AdapterItem(TorOnboardingDonateViewHolder.LAYOUT_ID)
|
148
|
|
-
|
149
|
141
|
object RecentTabsHeader : AdapterItem(RecentTabsHeaderViewHolder.LAYOUT_ID)
|
150
|
142
|
object RecentTabItem : AdapterItem(RecentTabViewHolder.LAYOUT_ID)
|
151
|
143
|
|
... |
... |
@@ -293,11 +285,6 @@ class SessionControlAdapter( |
293
|
285
|
viewLifecycleOwner = viewLifecycleOwner,
|
294
|
286
|
interactor = interactor,
|
295
|
287
|
)
|
296
|
|
- TorBootstrapPagerViewHolder.LAYOUT_ID -> TorBootstrapPagerViewHolder(
|
297
|
|
- view,
|
298
|
|
- components,
|
299
|
|
- interactor
|
300
|
|
- )
|
301
|
288
|
NoCollectionsMessageViewHolder.LAYOUT_ID ->
|
302
|
289
|
NoCollectionsMessageViewHolder(
|
303
|
290
|
view,
|
... |
... |
@@ -307,15 +294,6 @@ class SessionControlAdapter( |
307
|
294
|
interactor,
|
308
|
295
|
)
|
309
|
296
|
BottomSpacerViewHolder.LAYOUT_ID -> BottomSpacerViewHolder(view)
|
310
|
|
-
|
311
|
|
- TorOnboardingSecurityLevelViewHolder.LAYOUT_ID -> TorOnboardingSecurityLevelViewHolder(
|
312
|
|
- view,
|
313
|
|
- interactor
|
314
|
|
- )
|
315
|
|
- TorOnboardingDonateViewHolder.LAYOUT_ID -> TorOnboardingDonateViewHolder(
|
316
|
|
- view,
|
317
|
|
- interactor
|
318
|
|
- )
|
319
|
297
|
else -> throw IllegalStateException()
|
320
|
298
|
}
|
321
|
299
|
}
|
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt
... |
... |
@@ -134,21 +134,6 @@ interface SessionControlController { |
134
|
134
|
*/
|
135
|
135
|
fun handleTopSiteLongClicked(topSite: TopSite)
|
136
|
136
|
|
137
|
|
- /**
|
138
|
|
- * @see [OnboardingInteractor.onOpenSettingsClicked]
|
139
|
|
- */
|
140
|
|
- fun handleOpenSettingsClicked()
|
141
|
|
-
|
142
|
|
- /**
|
143
|
|
- * @see [OnboardingInteractor.onOpenSecurityLevelSettingsClicked]
|
144
|
|
- */
|
145
|
|
- fun handleOpenSecurityLevelSettingsClicked()
|
146
|
|
-
|
147
|
|
- /**
|
148
|
|
- * @see [OnboardingInteractor.onDonateClicked]
|
149
|
|
- */
|
150
|
|
- fun handleDonateClicked()
|
151
|
|
-
|
152
|
137
|
/**
|
153
|
138
|
* @see [CollectionInteractor.onToggleCollectionExpanded]
|
154
|
139
|
*/
|
... |
... |
@@ -188,31 +173,6 @@ interface SessionControlController { |
188
|
173
|
* @see [SessionControlInteractor.reportSessionMetrics]
|
189
|
174
|
*/
|
190
|
175
|
fun handleReportSessionMetrics(state: AppState)
|
191
|
|
-
|
192
|
|
- /**
|
193
|
|
- * @see [TorBootstrapInteractor.onTorBootstrapConnectClicked]
|
194
|
|
- */
|
195
|
|
- fun handleTorBootstrapConnectClicked()
|
196
|
|
-
|
197
|
|
- /**
|
198
|
|
- * @see [TorBootstrapInteractor.onTorStopBootstrapping]
|
199
|
|
- */
|
200
|
|
- fun handleTorStopBootstrapping()
|
201
|
|
-
|
202
|
|
- /**
|
203
|
|
- * @see [TorBootstrapInteractor.onTorStartBootstrapping]
|
204
|
|
- */
|
205
|
|
- fun handleTorStartBootstrapping()
|
206
|
|
-
|
207
|
|
- /**
|
208
|
|
- * @see [TorBootstrapInteractor.onTorStartDebugBootstrapping]
|
209
|
|
- */
|
210
|
|
- fun handleTorStartDebugBootstrapping()
|
211
|
|
-
|
212
|
|
- /**
|
213
|
|
- * @see [TorBootstrapInteractor.onTorBootstrapNetworkSettingsClicked]
|
214
|
|
- */
|
215
|
|
- fun handleTorNetworkSettingsClicked()
|
216
|
176
|
}
|
217
|
177
|
|
218
|
178
|
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList")
|
... |
... |
@@ -233,10 +193,6 @@ class DefaultSessionControlController( |
233
|
193
|
private val registerCollectionStorageObserver: () -> Unit,
|
234
|
194
|
private val removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit,
|
235
|
195
|
private val showTabTray: () -> Unit,
|
236
|
|
- private val handleTorBootstrapConnect: () -> Unit,
|
237
|
|
- private val initiateTorBootstrap: (Boolean) -> Unit,
|
238
|
|
- private val cancelTorBootstrap: () -> Unit,
|
239
|
|
- private val openTorNetworkSettings: () -> Unit
|
240
|
196
|
) : SessionControlController {
|
241
|
197
|
|
242
|
198
|
override fun handleCollectionAddTabTapped(collection: TabCollection) {
|
... |
... |
@@ -511,25 +467,6 @@ class DefaultSessionControlController( |
511
|
467
|
}
|
512
|
468
|
}
|
513
|
469
|
}
|
514
|
|
-
|
515
|
|
- override fun handleOpenSettingsClicked() {
|
516
|
|
- val directions = HomeFragmentDirections.actionGlobalPrivateBrowsingFragment()
|
517
|
|
- navController.nav(R.id.homeFragment, directions)
|
518
|
|
- }
|
519
|
|
-
|
520
|
|
- override fun handleOpenSecurityLevelSettingsClicked() {
|
521
|
|
- val directions = HomeFragmentDirections.actionGlobalTorSecurityLevelFragment()
|
522
|
|
- navController.nav(R.id.homeFragment, directions)
|
523
|
|
- }
|
524
|
|
-
|
525
|
|
- override fun handleDonateClicked() {
|
526
|
|
- activity.openToBrowserAndLoad(
|
527
|
|
- searchTermOrURL = SupportUtils.DONATE_URL,
|
528
|
|
- newTab = true,
|
529
|
|
- from = BrowserDirection.FromHome
|
530
|
|
- )
|
531
|
|
- }
|
532
|
|
-
|
533
|
470
|
override fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
|
534
|
471
|
appStore.dispatch(AppAction.CollectionExpanded(collection, expand))
|
535
|
472
|
}
|
... |
... |
@@ -601,24 +538,4 @@ class DefaultSessionControlController( |
601
|
538
|
|
602
|
539
|
RecentBookmarks.recentBookmarksCount.set(state.recentBookmarks.size.toLong())
|
603
|
540
|
}
|
604
|
|
-
|
605
|
|
- override fun handleTorBootstrapConnectClicked() {
|
606
|
|
- handleTorBootstrapConnect()
|
607
|
|
- }
|
608
|
|
-
|
609
|
|
- override fun handleTorStopBootstrapping() {
|
610
|
|
- cancelTorBootstrap()
|
611
|
|
- }
|
612
|
|
-
|
613
|
|
- override fun handleTorStartBootstrapping() {
|
614
|
|
- initiateTorBootstrap(false)
|
615
|
|
- }
|
616
|
|
-
|
617
|
|
- override fun handleTorStartDebugBootstrapping() {
|
618
|
|
- initiateTorBootstrap(true)
|
619
|
|
- }
|
620
|
|
-
|
621
|
|
- override fun handleTorNetworkSettingsClicked() {
|
622
|
|
- openTorNetworkSettings()
|
623
|
|
- }
|
624
|
541
|
} |
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt
... |
... |
@@ -129,26 +129,6 @@ interface CollectionInteractor { |
129
|
129
|
fun onRemoveCollectionsPlaceholder()
|
130
|
130
|
}
|
131
|
131
|
|
132
|
|
-/**
|
133
|
|
- * Interface for onboarding related actions in the [SessionControlInteractor].
|
134
|
|
- */
|
135
|
|
-interface OnboardingInteractor {
|
136
|
|
- /**
|
137
|
|
- * Hides the onboarding and navigates to Search. Called when a user clicks on the "Start Browsing" button.
|
138
|
|
- */
|
139
|
|
- fun onStartBrowsingClicked()
|
140
|
|
-
|
141
|
|
- /**
|
142
|
|
- * Hides the onboarding and navigates to Settings. Called when a user clicks on the "Open settings" button.
|
143
|
|
- */
|
144
|
|
- fun onOpenSettingsClicked()
|
145
|
|
-
|
146
|
|
- /**
|
147
|
|
- * Opens a custom tab to privacy notice url. Called when a user clicks on the "read our privacy notice" button.
|
148
|
|
- */
|
149
|
|
- fun onDonateClicked()
|
150
|
|
-}
|
151
|
|
-
|
152
|
132
|
interface CustomizeHomeIteractor {
|
153
|
133
|
/**
|
154
|
134
|
* Opens the customize home settings page.
|
... |
... |
@@ -156,34 +136,6 @@ interface CustomizeHomeIteractor { |
156
|
136
|
fun openCustomizeHomePage()
|
157
|
137
|
}
|
158
|
138
|
|
159
|
|
-interface TorBootstrapInteractor {
|
160
|
|
- /**
|
161
|
|
- * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
|
162
|
|
- */
|
163
|
|
- fun onTorBootstrapConnectClicked()
|
164
|
|
-
|
165
|
|
- /**
|
166
|
|
- * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
|
167
|
|
- */
|
168
|
|
- fun onTorStartBootstrapping()
|
169
|
|
-
|
170
|
|
- /**
|
171
|
|
- * Stop Tor bootstrapping. Called when a user clicks on the "settings" cog/button.
|
172
|
|
- */
|
173
|
|
- fun onTorStopBootstrapping()
|
174
|
|
-
|
175
|
|
- /**
|
176
|
|
- * Initiates Tor bootstrapping with debug logging. Called when bootstrapping fails with
|
177
|
|
- * the control.txt file not existing.
|
178
|
|
- */
|
179
|
|
- fun onTorStartDebugBootstrapping()
|
180
|
|
-
|
181
|
|
- /**
|
182
|
|
- * Open Tor Network Settings preference screen
|
183
|
|
- */
|
184
|
|
- fun onTorBootstrapNetworkSettingsClicked()
|
185
|
|
-}
|
186
|
|
-
|
187
|
139
|
/**
|
188
|
140
|
* Interface for top site related actions in the [SessionControlInteractor].
|
189
|
141
|
*/
|
... |
... |
@@ -295,7 +247,6 @@ class SessionControlInteractor( |
295
|
247
|
PocketStoriesInteractor,
|
296
|
248
|
PrivateBrowsingInteractor,
|
297
|
249
|
SearchSelectorInteractor,
|
298
|
|
- TorBootstrapInteractor,
|
299
|
250
|
WallpaperInteractor {
|
300
|
251
|
|
301
|
252
|
override fun onCollectionAddTabTapped(collection: TabCollection) {
|
... |
... |
@@ -358,15 +309,6 @@ class SessionControlInteractor( |
358
|
309
|
return controller.handleShowWallpapersOnboardingDialog(state)
|
359
|
310
|
}
|
360
|
311
|
|
361
|
|
- // TODO: Do these still work, if not overrides, cus parent class dropped, are they wired in still?
|
362
|
|
- fun onOpenSettingsClicked() {
|
363
|
|
- controller.handleOpenSettingsClicked()
|
364
|
|
- }
|
365
|
|
-
|
366
|
|
- fun onDonateClicked() {
|
367
|
|
- controller.handleDonateClicked()
|
368
|
|
- }
|
369
|
|
-
|
370
|
312
|
override fun onToggleCollectionExpanded(collection: TabCollection, expand: Boolean) {
|
371
|
313
|
controller.handleToggleCollectionExpanded(collection, expand)
|
372
|
314
|
}
|
... |
... |
@@ -500,24 +442,4 @@ class SessionControlInteractor( |
500
|
442
|
override fun onMenuItemTapped(item: SearchSelectorMenu.Item) {
|
501
|
443
|
searchSelectorController.handleMenuItemTapped(item)
|
502
|
444
|
}
|
503
|
|
-
|
504
|
|
- override fun onTorBootstrapConnectClicked() {
|
505
|
|
- controller.handleTorBootstrapConnectClicked()
|
506
|
|
- }
|
507
|
|
-
|
508
|
|
- override fun onTorStopBootstrapping() {
|
509
|
|
- controller.handleTorStopBootstrapping()
|
510
|
|
- }
|
511
|
|
-
|
512
|
|
- override fun onTorStartBootstrapping() {
|
513
|
|
- controller.handleTorStartBootstrapping()
|
514
|
|
- }
|
515
|
|
-
|
516
|
|
- override fun onTorStartDebugBootstrapping() {
|
517
|
|
- controller.handleTorStartDebugBootstrapping()
|
518
|
|
- }
|
519
|
|
-
|
520
|
|
- override fun onTorBootstrapNetworkSettingsClicked() {
|
521
|
|
- controller.handleTorNetworkSettingsClicked()
|
522
|
|
- }
|
523
|
445
|
} |
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlView.kt
... |
... |
@@ -126,15 +126,6 @@ private fun showCollections( |
126
|
126
|
|
127
|
127
|
private fun privateModeAdapterItems() = listOf(AdapterItem.PrivateBrowsingDescription)
|
128
|
128
|
|
129
|
|
-private fun bootstrapAdapterItems() = listOf(AdapterItem.TorBootstrap)
|
130
|
|
-
|
131
|
|
-private fun torOnboardingAdapterItems() =
|
132
|
|
- listOf(
|
133
|
|
- AdapterItem.TorOnboardingSecurityLevel,
|
134
|
|
- AdapterItem.TorOnboardingDonate,
|
135
|
|
- // AdapterItem.OnboardingFinish
|
136
|
|
- )
|
137
|
|
-
|
138
|
129
|
private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when (mode) {
|
139
|
130
|
is Mode.Normal -> normalModeAdapterItems(
|
140
|
131
|
settings,
|
... |
... |
@@ -151,7 +142,6 @@ private fun AppState.toAdapterList(settings: Settings): List<AdapterItem> = when |
151
|
142
|
firstFrameDrawn,
|
152
|
143
|
)
|
153
|
144
|
is Mode.Private -> privateModeAdapterItems()
|
154
|
|
- is Mode.Bootstrap -> bootstrapAdapterItems()
|
155
|
145
|
}
|
156
|
146
|
|
157
|
147
|
private fun collectionTabItems(collection: TabCollection) =
|
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingDonateViewHolder.kt
deleted
1
|
|
-/* This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
|
- * License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
|
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4
|
|
-
|
5
|
|
-package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
6
|
|
-
|
7
|
|
-import android.view.View
|
8
|
|
-import androidx.recyclerview.widget.RecyclerView
|
9
|
|
-import org.mozilla.fenix.R
|
10
|
|
-import org.mozilla.fenix.databinding.TorOnboardingDonateBinding
|
11
|
|
-import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
|
12
|
|
-
|
13
|
|
-class TorOnboardingDonateViewHolder(
|
14
|
|
- view: View,
|
15
|
|
- private val interactor: SessionControlInteractor
|
16
|
|
-) : RecyclerView.ViewHolder(view) {
|
17
|
|
-
|
18
|
|
- init {
|
19
|
|
- val binding = TorOnboardingDonateBinding.bind(view)
|
20
|
|
- binding.donateNowButton.setOnClickListener {
|
21
|
|
- interactor.onDonateClicked()
|
22
|
|
- }
|
23
|
|
- }
|
24
|
|
-
|
25
|
|
- companion object {
|
26
|
|
- const val LAYOUT_ID = R.layout.tor_onboarding_donate
|
27
|
|
- }
|
28
|
|
-} |
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/TorOnboardingSecurityLevelViewHolder.kt
deleted
1
|
|
-/* This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
|
- * License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
|
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4
|
|
-
|
5
|
|
-package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
6
|
|
-
|
7
|
|
-import android.view.View
|
8
|
|
-import androidx.recyclerview.widget.RecyclerView
|
9
|
|
-import org.mozilla.fenix.R
|
10
|
|
-import org.mozilla.fenix.databinding.TorOnboardingSecurityLevelBinding
|
11
|
|
-import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
|
12
|
|
-import org.mozilla.fenix.ext.components
|
13
|
|
-import org.mozilla.fenix.onboarding.OnboardingRadioButton
|
14
|
|
-import org.mozilla.fenix.tor.SecurityLevel
|
15
|
|
-import org.mozilla.fenix.tor.SecurityLevelUtil
|
16
|
|
-import org.mozilla.fenix.utils.view.addToRadioGroup
|
17
|
|
-
|
18
|
|
-class TorOnboardingSecurityLevelViewHolder(
|
19
|
|
- view: View,
|
20
|
|
- private val interactor: SessionControlInteractor
|
21
|
|
-) : RecyclerView.ViewHolder(view) {
|
22
|
|
-
|
23
|
|
- private var _binding: TorOnboardingSecurityLevelBinding? = null
|
24
|
|
- private val binding get() = _binding!!
|
25
|
|
-
|
26
|
|
- private var standardSecurityLevel: OnboardingRadioButton
|
27
|
|
- private var saferSecurityLevel: OnboardingRadioButton
|
28
|
|
- private var safestSecurityLevel: OnboardingRadioButton
|
29
|
|
-
|
30
|
|
- init {
|
31
|
|
- _binding = TorOnboardingSecurityLevelBinding.bind(view)
|
32
|
|
- binding.headerText.setOnboardingIcon(R.drawable.ic_onboarding_tracking_protection)
|
33
|
|
-
|
34
|
|
- standardSecurityLevel = binding.securityLevelStandardOption
|
35
|
|
- saferSecurityLevel = binding.securityLevelSaferOption
|
36
|
|
- safestSecurityLevel = binding.securityLevelSafestOption
|
37
|
|
-
|
38
|
|
- binding.descriptionText.text = view.context.getString(
|
39
|
|
- R.string.tor_onboarding_security_level_description
|
40
|
|
- )
|
41
|
|
-
|
42
|
|
- setupRadioGroup(view)
|
43
|
|
-
|
44
|
|
- }
|
45
|
|
-
|
46
|
|
- private fun setupRadioGroup(view: View) {
|
47
|
|
-
|
48
|
|
- addToRadioGroup(standardSecurityLevel, saferSecurityLevel, safestSecurityLevel)
|
49
|
|
-
|
50
|
|
- val securityLevel = try {
|
51
|
|
- SecurityLevelUtil.getSecurityLevelFromInt(
|
52
|
|
- view.context.components.core.engine.settings.torSecurityLevel
|
53
|
|
- )
|
54
|
|
- } catch (e: IllegalStateException) {
|
55
|
|
- SecurityLevel.STANDARD
|
56
|
|
- }
|
57
|
|
-
|
58
|
|
- standardSecurityLevel.isChecked = securityLevel == SecurityLevel.STANDARD
|
59
|
|
- safestSecurityLevel.isChecked = securityLevel == SecurityLevel.SAFEST
|
60
|
|
- saferSecurityLevel.isChecked = securityLevel == SecurityLevel.SAFER
|
61
|
|
-
|
62
|
|
- standardSecurityLevel.onClickListener {
|
63
|
|
- updateSecurityLevel(SecurityLevel.STANDARD, view)
|
64
|
|
- }
|
65
|
|
-
|
66
|
|
- saferSecurityLevel.onClickListener {
|
67
|
|
- updateSecurityLevel(SecurityLevel.SAFER, view)
|
68
|
|
- }
|
69
|
|
-
|
70
|
|
- safestSecurityLevel.onClickListener {
|
71
|
|
- updateSecurityLevel(SecurityLevel.SAFEST, view)
|
72
|
|
- }
|
73
|
|
-
|
74
|
|
- updateSecurityLevel(securityLevel, view)
|
75
|
|
- }
|
76
|
|
-
|
77
|
|
- private fun updateSecurityLevel(newLevel: SecurityLevel, view: View) {
|
78
|
|
- val resources = view.context.resources
|
79
|
|
- val securityLevel = when (newLevel) {
|
80
|
|
- SecurityLevel.STANDARD -> resources.getString(R.string.tor_security_level_standard_option)
|
81
|
|
- SecurityLevel.SAFER -> resources.getString(R.string.tor_security_level_safer_option)
|
82
|
|
- SecurityLevel.SAFEST -> resources.getString(R.string.tor_security_level_safest_option)
|
83
|
|
- }
|
84
|
|
- binding.currentLevel.text = resources.getString(
|
85
|
|
- R.string.tor_onboarding_chosen_security_level_label, securityLevel
|
86
|
|
- )
|
87
|
|
- view.context.components.let {
|
88
|
|
- it.core.engine.settings.torSecurityLevel = newLevel.intRepresentation
|
89
|
|
- }
|
90
|
|
- }
|
91
|
|
-
|
92
|
|
- companion object {
|
93
|
|
- const val LAYOUT_ID = R.layout.tor_onboarding_security_level
|
94
|
|
- }
|
95
|
|
-} |
fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapFragment.kt
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+package org.mozilla.fenix.tor
|
|
6
|
+
|
|
7
|
+import android.os.Bundle
|
|
8
|
+import android.view.LayoutInflater
|
|
9
|
+import android.view.View
|
|
10
|
+import android.view.ViewGroup
|
|
11
|
+import androidx.annotation.VisibleForTesting
|
|
12
|
+import androidx.core.view.children
|
|
13
|
+import androidx.fragment.app.Fragment
|
|
14
|
+import androidx.lifecycle.lifecycleScope
|
|
15
|
+import org.mozilla.fenix.BuildConfig
|
|
16
|
+import org.mozilla.fenix.databinding.FragmentHomeBinding
|
|
17
|
+import org.mozilla.fenix.ext.requireComponents
|
|
18
|
+import org.mozilla.fenix.tor.bootstrap.TorQuickStart
|
|
19
|
+import org.mozilla.fenix.tor.interactor.DefaultTorBootstrapInteractor
|
|
20
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
|
21
|
+import androidx.navigation.fragment.findNavController
|
|
22
|
+import com.google.android.material.appbar.AppBarLayout
|
|
23
|
+import org.mozilla.fenix.ext.components
|
|
24
|
+import org.mozilla.fenix.ext.hideToolbar
|
|
25
|
+import org.mozilla.fenix.tor.controller.DefaultTorBootstrapController
|
|
26
|
+import org.mozilla.fenix.tor.view.TorBootstrapView
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+@Suppress("TooManyFunctions", "LargeClass")
|
|
30
|
+class TorBootstrapFragment : Fragment() {
|
|
31
|
+ private val torQuickStart by lazy { TorQuickStart(requireContext()) }
|
|
32
|
+
|
|
33
|
+ internal var _binding: FragmentHomeBinding? = null
|
|
34
|
+ private val binding get() = _binding!!
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+ private var torBootstrapView: TorBootstrapView? = null
|
|
38
|
+
|
|
39
|
+ private var _torBootstrapInteractor: TorBootstrapInteractor? = null
|
|
40
|
+ private val torBootstrapInteractor: TorBootstrapInteractor
|
|
41
|
+ get() = _torBootstrapInteractor!!
|
|
42
|
+
|
|
43
|
+ private lateinit var torBootstrapStatus: TorBootstrapStatus
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+ @Suppress("LongMethod")
|
|
47
|
+ override fun onCreateView(
|
|
48
|
+ inflater: LayoutInflater,
|
|
49
|
+ container: ViewGroup?,
|
|
50
|
+ savedInstanceState: Bundle?,
|
|
51
|
+ ): View {
|
|
52
|
+ _binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
53
|
+ val components = requireComponents
|
|
54
|
+
|
|
55
|
+ torBootstrapStatus = TorBootstrapStatus(
|
|
56
|
+ torQuickStart,
|
|
57
|
+ !BuildConfig.DISABLE_TOR,
|
|
58
|
+ components.torController,
|
|
59
|
+ ::dispatchModeChanges
|
|
60
|
+ )
|
|
61
|
+
|
|
62
|
+ if (!torBootstrapStatus.isBootstrapping()) {
|
|
63
|
+ openHome()
|
|
64
|
+ }
|
|
65
|
+
|
|
66
|
+ // Was _sessionControlInteractor
|
|
67
|
+ _torBootstrapInteractor = DefaultTorBootstrapInteractor(
|
|
68
|
+ controller = DefaultTorBootstrapController(
|
|
69
|
+ handleTorBootstrapConnect = ::handleTorBootstrapConnect,
|
|
70
|
+ cancelTorBootstrap = ::cancelTorBootstrap,
|
|
71
|
+ initiateTorBootstrap = ::initiateTorBootstrap,
|
|
72
|
+ openTorNetworkSettings = ::openTorNetworkSettings
|
|
73
|
+ ),
|
|
74
|
+ )
|
|
75
|
+
|
|
76
|
+ torBootstrapView = TorBootstrapView(
|
|
77
|
+ containerView = binding.sessionControlRecyclerView,
|
|
78
|
+ viewLifecycleOwner = viewLifecycleOwner,
|
|
79
|
+ interactor = torBootstrapInteractor,
|
|
80
|
+ )
|
|
81
|
+
|
|
82
|
+ adjustHomeFragmentView()
|
|
83
|
+ updateSessionControlView()
|
|
84
|
+ showSessionControlView()
|
|
85
|
+
|
|
86
|
+ return binding.root
|
|
87
|
+ }
|
|
88
|
+
|
|
89
|
+ private fun updateSessionControlView() {
|
|
90
|
+ torBootstrapView?.update(requireContext().components.appStore.state)
|
|
91
|
+ }
|
|
92
|
+
|
|
93
|
+ // This function should be paired with showSessionControlView()
|
|
94
|
+ private fun adjustHomeFragmentView() {
|
|
95
|
+ binding.sessionControlRecyclerView.apply {
|
|
96
|
+ visibility = View.INVISIBLE
|
|
97
|
+ }
|
|
98
|
+
|
|
99
|
+ binding.sessionControlRecyclerView.apply {
|
|
100
|
+ setPadding(0, 0, 0, 0)
|
|
101
|
+ (layoutParams as ViewGroup.MarginLayoutParams).setMargins(0, 0, 0, 0)
|
|
102
|
+ }
|
|
103
|
+
|
|
104
|
+ binding.homeAppBar.apply {
|
|
105
|
+ visibility = View.GONE
|
|
106
|
+
|
|
107
|
+ // Reset this as SCROLL in case it was previously set as NO_SCROLL after bootstrap
|
|
108
|
+ children.forEach {
|
|
109
|
+ (it.layoutParams as AppBarLayout.LayoutParams).scrollFlags =
|
|
110
|
+ AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
|
|
111
|
+ }
|
|
112
|
+ }
|
|
113
|
+ binding.onionPatternImage.apply {
|
|
114
|
+ visibility = View.GONE
|
|
115
|
+ }
|
|
116
|
+ binding.toolbarLayout.apply {
|
|
117
|
+ visibility = View.GONE
|
|
118
|
+ }
|
|
119
|
+ }
|
|
120
|
+
|
|
121
|
+ // This function should be paired with adjustHomeFragmentView()
|
|
122
|
+ private fun showSessionControlView() {
|
|
123
|
+ binding.sessionControlRecyclerView.apply {
|
|
124
|
+ visibility = View.VISIBLE
|
|
125
|
+ }
|
|
126
|
+ }
|
|
127
|
+
|
|
128
|
+ private fun dispatchModeChanges(isBootstrapping: Boolean) {
|
|
129
|
+ //requireComponents.appStore.dispatch(AppAction.ModeChange(mode))
|
|
130
|
+ if (!isBootstrapping) {
|
|
131
|
+ openHome()
|
|
132
|
+ } else {
|
|
133
|
+ adjustHomeFragmentView()
|
|
134
|
+ updateSessionControlView()
|
|
135
|
+ showSessionControlView()
|
|
136
|
+ }
|
|
137
|
+ }
|
|
138
|
+
|
|
139
|
+ override fun onStop() {
|
|
140
|
+ super.onStop()
|
|
141
|
+ torBootstrapStatus.unregisterTorListener()
|
|
142
|
+ }
|
|
143
|
+
|
|
144
|
+ override fun onResume() {
|
|
145
|
+ super.onResume()
|
|
146
|
+
|
|
147
|
+ torBootstrapStatus.registerTorListener()
|
|
148
|
+
|
|
149
|
+ // fenix#40176: Ensure the Home fragment is rendered correctly when we resume.
|
|
150
|
+ val isBootstraping = torBootstrapStatus.isBootstrapping()
|
|
151
|
+
|
|
152
|
+ if (!isBootstraping) {
|
|
153
|
+ openHome()
|
|
154
|
+ }
|
|
155
|
+
|
|
156
|
+ adjustHomeFragmentView()
|
|
157
|
+ updateSessionControlView()
|
|
158
|
+ showSessionControlView()
|
|
159
|
+
|
|
160
|
+ hideToolbar()
|
|
161
|
+
|
|
162
|
+ // Whenever a tab is selected its last access timestamp is automatically updated by A-C.
|
|
163
|
+ // However, in the case of resuming the app to the home fragment, we already have an
|
|
164
|
+ // existing selected tab, but its last access timestamp is outdated. No action is
|
|
165
|
+ // triggered to cause an automatic update on warm start (no tab selection occurs). So we
|
|
166
|
+ // update it manually here.
|
|
167
|
+ requireComponents.useCases.sessionUseCases.updateLastAccess()
|
|
168
|
+ }
|
|
169
|
+
|
|
170
|
+ private fun handleTorBootstrapConnect() {
|
|
171
|
+ requireComponents.torController.onTorConnecting()
|
|
172
|
+ }
|
|
173
|
+
|
|
174
|
+ private fun cancelTorBootstrap() {
|
|
175
|
+ requireComponents.torController.stopTor()
|
|
176
|
+ }
|
|
177
|
+
|
|
178
|
+ private fun initiateTorBootstrap(withDebugLogging: Boolean = false) {
|
|
179
|
+ requireComponents.torController.initiateTorBootstrap(lifecycleScope, withDebugLogging)
|
|
180
|
+ }
|
|
181
|
+
|
|
182
|
+ private fun openTorNetworkSettings() {
|
|
183
|
+ val directions =
|
|
184
|
+ TorBootstrapFragmentDirections.actionTorbootstrapFragmentToTorNetworkSettingsFragment()
|
|
185
|
+ findNavController().navigate(directions)
|
|
186
|
+ }
|
|
187
|
+
|
|
188
|
+ private fun openHome() {
|
|
189
|
+ val directions =
|
|
190
|
+ TorBootstrapFragmentDirections
|
|
191
|
+ .actionStartupHome()
|
|
192
|
+ findNavController().navigate(directions)
|
|
193
|
+ }
|
|
194
|
+
|
|
195
|
+} |
fenix/app/src/main/java/org/mozilla/fenix/tor/TorBootstrapStatus.kt
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+package org.mozilla.fenix.tor
|
|
6
|
+
|
|
7
|
+import org.mozilla.fenix.tor.bootstrap.TorQuickStart
|
|
8
|
+
|
|
9
|
+@SuppressWarnings("LongParameterList", "TooManyFunctions")
|
|
10
|
+class TorBootstrapStatus(
|
|
11
|
+ private val torQuickStart: TorQuickStart,
|
|
12
|
+ private val shouldStartTor: Boolean,
|
|
13
|
+ private val torController: TorController,
|
|
14
|
+ private val dispatchModeChanges: (isShouldBootstrap: Boolean) -> Unit
|
|
15
|
+ ) : TorEvents {
|
|
16
|
+
|
|
17
|
+ init {
|
|
18
|
+ torController.registerTorListener(this)
|
|
19
|
+ }
|
|
20
|
+
|
|
21
|
+ fun isBootstrapping() = (shouldStartTor && (!torQuickStart.quickStartTor() && !torController.isBootstrapped))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+ @SuppressWarnings("EmptyFunctionBlock")
|
|
25
|
+ override fun onTorConnecting() {
|
|
26
|
+ }
|
|
27
|
+
|
|
28
|
+ override fun onTorConnected() {
|
|
29
|
+ dispatchModeChanges(isBootstrapping())
|
|
30
|
+ }
|
|
31
|
+
|
|
32
|
+ override fun onTorStopped() {
|
|
33
|
+ dispatchModeChanges(isBootstrapping())
|
|
34
|
+ }
|
|
35
|
+
|
|
36
|
+ @SuppressWarnings("EmptyFunctionBlock")
|
|
37
|
+ override fun onTorStatusUpdate(entry: String?, status: String?) {
|
|
38
|
+ }
|
|
39
|
+
|
|
40
|
+ fun unregisterTorListener() {
|
|
41
|
+ torController.unregisterTorListener(this)
|
|
42
|
+ }
|
|
43
|
+
|
|
44
|
+ fun registerTorListener() {
|
|
45
|
+ torController.registerTorListener(this)
|
|
46
|
+ }
|
|
47
|
+
|
|
48
|
+} |
fenix/app/src/main/java/org/mozilla/fenix/tor/controller/TorBootstrapController.kt
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+package org.mozilla.fenix.tor.controller
|
|
6
|
+
|
|
7
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
|
8
|
+
|
|
9
|
+interface TorBootstrapController {
|
|
10
|
+ /**
|
|
11
|
+ * @see [TorBootstrapInteractor.onTorBootstrapConnectClicked]
|
|
12
|
+ */
|
|
13
|
+ fun handleTorBootstrapConnectClicked()
|
|
14
|
+
|
|
15
|
+ /**
|
|
16
|
+ * @see [TorBootstrapInteractor.onTorStopBootstrapping]
|
|
17
|
+ */
|
|
18
|
+ fun handleTorStopBootstrapping()
|
|
19
|
+
|
|
20
|
+ /**
|
|
21
|
+ * @see [TorBootstrapInteractor.onTorStartBootstrapping]
|
|
22
|
+ */
|
|
23
|
+ fun handleTorStartBootstrapping()
|
|
24
|
+
|
|
25
|
+ /**
|
|
26
|
+ * @see [TorBootstrapInteractor.onTorStartDebugBootstrapping]
|
|
27
|
+ */
|
|
28
|
+ fun handleTorStartDebugBootstrapping()
|
|
29
|
+
|
|
30
|
+ /**
|
|
31
|
+ * @see [TorBootstrapInteractor.onTorBootstrapNetworkSettingsClicked]
|
|
32
|
+ */
|
|
33
|
+ fun handleTorNetworkSettingsClicked()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+}
|
|
37
|
+
|
|
38
|
+class DefaultTorBootstrapController(
|
|
39
|
+ private val handleTorBootstrapConnect: () -> Unit,
|
|
40
|
+ private val initiateTorBootstrap: (Boolean) -> Unit,
|
|
41
|
+ private val cancelTorBootstrap: () -> Unit,
|
|
42
|
+ private val openTorNetworkSettings: () -> Unit
|
|
43
|
+) : TorBootstrapController {
|
|
44
|
+ override fun handleTorBootstrapConnectClicked() {
|
|
45
|
+ handleTorBootstrapConnect()
|
|
46
|
+ }
|
|
47
|
+
|
|
48
|
+ override fun handleTorStopBootstrapping() {
|
|
49
|
+ cancelTorBootstrap()
|
|
50
|
+ }
|
|
51
|
+
|
|
52
|
+ override fun handleTorStartBootstrapping() {
|
|
53
|
+ initiateTorBootstrap(false)
|
|
54
|
+ }
|
|
55
|
+
|
|
56
|
+ override fun handleTorStartDebugBootstrapping() {
|
|
57
|
+ initiateTorBootstrap(true)
|
|
58
|
+ }
|
|
59
|
+
|
|
60
|
+ override fun handleTorNetworkSettingsClicked() {
|
|
61
|
+ openTorNetworkSettings()
|
|
62
|
+ }
|
|
63
|
+} |
fenix/app/src/main/java/org/mozilla/fenix/tor/interactor/TorBootstrapInteractor.kt
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+package org.mozilla.fenix.tor.interactor
|
|
6
|
+
|
|
7
|
+import org.mozilla.fenix.tor.controller.TorBootstrapController
|
|
8
|
+
|
|
9
|
+interface TorBootstrapInteractor {
|
|
10
|
+ /**
|
|
11
|
+ * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
|
|
12
|
+ */
|
|
13
|
+ fun onTorBootstrapConnectClicked()
|
|
14
|
+
|
|
15
|
+ /**
|
|
16
|
+ * Initiates Tor bootstrapping. Called when a user clicks on the "Connect" button.
|
|
17
|
+ */
|
|
18
|
+ fun onTorStartBootstrapping()
|
|
19
|
+
|
|
20
|
+ /**
|
|
21
|
+ * Stop Tor bootstrapping. Called when a user clicks on the "settings" cog/button.
|
|
22
|
+ */
|
|
23
|
+ fun onTorStopBootstrapping()
|
|
24
|
+
|
|
25
|
+ /**
|
|
26
|
+ * Initiates Tor bootstrapping with debug logging. Called when bootstrapping fails with
|
|
27
|
+ * the control.txt file not existing.
|
|
28
|
+ */
|
|
29
|
+ fun onTorStartDebugBootstrapping()
|
|
30
|
+
|
|
31
|
+ /**
|
|
32
|
+ * Open Tor Network Settings preference screen
|
|
33
|
+ */
|
|
34
|
+ fun onTorBootstrapNetworkSettingsClicked()
|
|
35
|
+}
|
|
36
|
+
|
|
37
|
+class DefaultTorBootstrapInteractor(
|
|
38
|
+ private val controller: TorBootstrapController,
|
|
39
|
+) : TorBootstrapInteractor {
|
|
40
|
+
|
|
41
|
+ override fun onTorBootstrapConnectClicked() {
|
|
42
|
+ controller.handleTorBootstrapConnectClicked()
|
|
43
|
+ }
|
|
44
|
+
|
|
45
|
+ override fun onTorStopBootstrapping() {
|
|
46
|
+ controller.handleTorStopBootstrapping()
|
|
47
|
+ }
|
|
48
|
+
|
|
49
|
+ override fun onTorStartBootstrapping() {
|
|
50
|
+ controller.handleTorStartBootstrapping()
|
|
51
|
+ }
|
|
52
|
+
|
|
53
|
+ override fun onTorStartDebugBootstrapping() {
|
|
54
|
+ controller.handleTorStartDebugBootstrapping()
|
|
55
|
+ }
|
|
56
|
+
|
|
57
|
+ override fun onTorBootstrapNetworkSettingsClicked() {
|
|
58
|
+ controller.handleTorNetworkSettingsClicked()
|
|
59
|
+ }
|
|
60
|
+} |
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapAdapter.kt
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+package org.mozilla.fenix.tor.view
|
|
6
|
+
|
|
7
|
+import android.view.LayoutInflater
|
|
8
|
+import android.view.ViewGroup
|
|
9
|
+import androidx.annotation.LayoutRes
|
|
10
|
+import androidx.lifecycle.LifecycleOwner
|
|
11
|
+import androidx.recyclerview.widget.DiffUtil
|
|
12
|
+import androidx.recyclerview.widget.ListAdapter
|
|
13
|
+import androidx.recyclerview.widget.RecyclerView
|
|
14
|
+import org.mozilla.fenix.components.Components
|
|
15
|
+import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
|
|
16
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
|
17
|
+
|
|
18
|
+sealed class AdapterItem(@LayoutRes val viewType: Int) {
|
|
19
|
+ object TorBootstrap : AdapterItem(TorBootstrapPagerViewHolder.LAYOUT_ID)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+ open fun sameAs(other: AdapterItem) = this::class == other::class
|
|
23
|
+ open fun getChangePayload(newItem: AdapterItem): Any? = null
|
|
24
|
+ open fun contentsSameAs(other: AdapterItem) = this::class == other::class
|
|
25
|
+
|
|
26
|
+}
|
|
27
|
+
|
|
28
|
+class AdapterItemDiffCallback : DiffUtil.ItemCallback<AdapterItem>() {
|
|
29
|
+ override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
|
|
30
|
+ oldItem.sameAs(newItem)
|
|
31
|
+
|
|
32
|
+ @Suppress("DiffUtilEquals")
|
|
33
|
+ override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
|
|
34
|
+ oldItem.contentsSameAs(newItem)
|
|
35
|
+
|
|
36
|
+ override fun getChangePayload(oldItem: AdapterItem, newItem: AdapterItem): Any? {
|
|
37
|
+ return oldItem.getChangePayload(newItem) ?: return super.getChangePayload(oldItem, newItem)
|
|
38
|
+ }
|
|
39
|
+}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+class TorBootstrapAdapter(
|
|
44
|
+ private val interactor: TorBootstrapInteractor,
|
|
45
|
+ private val viewLifecycleOwner: LifecycleOwner,
|
|
46
|
+ private val components: Components,
|
|
47
|
+) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) {
|
|
48
|
+
|
|
49
|
+ // This method triggers the ComplexMethod lint error when in fact it's quite simple.
|
|
50
|
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
|
51
|
+ val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
|
|
52
|
+ return when (viewType) {
|
|
53
|
+ TorBootstrapPagerViewHolder.LAYOUT_ID -> TorBootstrapPagerViewHolder(
|
|
54
|
+ view,
|
|
55
|
+ components,
|
|
56
|
+ interactor
|
|
57
|
+ )
|
|
58
|
+ else -> throw IllegalStateException()
|
|
59
|
+ }
|
|
60
|
+ }
|
|
61
|
+
|
|
62
|
+ override fun getItemViewType(position: Int) = getItem(position).viewType
|
|
63
|
+
|
|
64
|
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) {
|
|
65
|
+ if (payloads.isEmpty()) {
|
|
66
|
+ onBindViewHolder(holder, position)
|
|
67
|
+ } else {
|
|
68
|
+ when (holder) {
|
|
69
|
+ is TopSitePagerViewHolder -> {
|
|
70
|
+ if (payloads[0] is org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload) {
|
|
71
|
+ val payload = payloads[0] as org.mozilla.fenix.home.sessioncontrol.AdapterItem.TopSitePagerPayload
|
|
72
|
+ holder.update(payload)
|
|
73
|
+ }
|
|
74
|
+ }
|
|
75
|
+ }
|
|
76
|
+ }
|
|
77
|
+ }
|
|
78
|
+
|
|
79
|
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
|
80
|
+ // no-op. This ViewHolder receives the HomeStore as argument and will observe that
|
|
81
|
+ // without the need for us to manually update from here the data to be displayed.
|
|
82
|
+ }
|
|
83
|
+} |
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapConnectViewHolder.kt
→
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapConnectViewHolder.kt
... |
... |
@@ -2,17 +2,16 @@ |
2
|
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
3
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4
|
4
|
|
5
|
|
-package org.mozilla.fenix.home.sessioncontrol.viewholders
|
|
5
|
+package org.mozilla.fenix.tor.view
|
6
|
6
|
|
7
|
7
|
import android.view.View
|
8
|
|
-import androidx.appcompat.widget.SwitchCompat
|
9
|
8
|
import androidx.recyclerview.widget.RecyclerView
|
10
|
9
|
import org.mozilla.fenix.R
|
|
10
|
+import org.mozilla.fenix.components.Components
|
11
|
11
|
import org.mozilla.fenix.databinding.TorBootstrapConnectBinding
|
12
|
12
|
import org.mozilla.fenix.tor.TorEvents
|
13
|
13
|
import org.mozilla.fenix.tor.bootstrap.TorQuickStart
|
14
|
|
-import org.mozilla.fenix.components.Components
|
15
|
|
-import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
|
|
14
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
16
|
15
|
|
17
|
16
|
class TorBootstrapConnectViewHolder(
|
18
|
17
|
private val view: View,
|
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapLoggerViewHolder.kt
→
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapLoggerViewHolder.kt
... |
... |
@@ -2,20 +2,20 @@ |
2
|
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
3
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4
|
4
|
|
5
|
|
-package org.mozilla.fenix.home.sessioncontrol.viewholders
|
|
5
|
+package org.mozilla.fenix.tor.view
|
6
|
6
|
|
7
|
7
|
import android.text.method.ScrollingMovementMethod
|
8
|
8
|
import android.view.View
|
9
|
9
|
import androidx.recyclerview.widget.RecyclerView
|
10
|
10
|
import org.mozilla.fenix.R
|
|
11
|
+import org.mozilla.fenix.components.Components
|
11
|
12
|
import org.mozilla.fenix.databinding.TorBootstrapLoggerBinding
|
12
|
13
|
import org.mozilla.fenix.tor.TorEvents
|
13
|
|
-import org.mozilla.fenix.components.Components
|
14
|
14
|
|
15
|
15
|
class TorBootstrapLoggerViewHolder(
|
16
|
|
- private val view: View,
|
17
|
|
- private val components: Components
|
18
|
|
-) : RecyclerView.ViewHolder(view), TorEvents {
|
|
16
|
+ private val view: View,
|
|
17
|
+ private val components: Components
|
|
18
|
+ ) : RecyclerView.ViewHolder(view), TorEvents {
|
19
|
19
|
|
20
|
20
|
private var entries = mutableListOf<String>()
|
21
|
21
|
private var binding: TorBootstrapLoggerBinding
|
... |
... |
@@ -25,10 +25,10 @@ class TorBootstrapLoggerViewHolder( |
25
|
25
|
components.torController.registerTorListener(this)
|
26
|
26
|
|
27
|
27
|
val currentEntries = components.torController.logEntries
|
28
|
|
- .filter { it.first != null }
|
29
|
|
- .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
|
30
|
|
- // Keep synchronized with format in onTorStatusUpdate
|
31
|
|
- .flatMap { listOf("(${it.second}) '${it.first}'") }
|
|
28
|
+ .filter { it.first != null }
|
|
29
|
+ .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
|
|
30
|
+ // Keep synchronized with format in onTorStatusUpdate
|
|
31
|
+ .flatMap { listOf("(${it.second}) '${it.first}'") }
|
32
|
32
|
val entriesLen = currentEntries.size
|
33
|
33
|
val subListOffset = if (entriesLen > MAX_NEW_ENTRIES) MAX_NEW_ENTRIES else entriesLen
|
34
|
34
|
entries = currentEntries.subList((entriesLen - subListOffset), entriesLen) as MutableList<String>
|
... |
... |
@@ -72,4 +72,5 @@ class TorBootstrapLoggerViewHolder( |
72
|
72
|
const val MAX_NEW_ENTRIES = 24
|
73
|
73
|
const val MAX_LINES = 25
|
74
|
74
|
}
|
|
75
|
+
|
75
|
76
|
} |
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/torbootstrap/BootstrapPagerAdapter.kt
→
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerAdapter.kt
... |
... |
@@ -2,18 +2,15 @@ |
2
|
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
3
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4
|
4
|
|
5
|
|
-package org.mozilla.fenix.home.sessioncontrol.viewholders.torbootstrap
|
|
5
|
+package org.mozilla.fenix.tor.view
|
6
|
6
|
|
7
|
7
|
import android.view.LayoutInflater
|
8
|
8
|
import android.view.ViewGroup
|
9
|
9
|
import androidx.recyclerview.widget.RecyclerView
|
10
|
|
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
11
|
10
|
import org.mozilla.fenix.components.Components
|
12
|
|
-import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
|
13
|
|
-import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapConnectViewHolder
|
14
|
|
-import org.mozilla.fenix.home.sessioncontrol.viewholders.TorBootstrapLoggerViewHolder
|
|
11
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
15
|
12
|
|
16
|
|
-class BootstrapPagerAdapter(
|
|
13
|
+class TorBootstrapPagerAdapter(
|
17
|
14
|
private val components: Components,
|
18
|
15
|
private val interactor: TorBootstrapInteractor
|
19
|
16
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
fenix/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TorBootstrapPagerViewHolder.kt
→
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapPagerViewHolder.kt
... |
... |
@@ -2,23 +2,22 @@ |
2
|
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
3
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4
|
4
|
|
5
|
|
-package org.mozilla.fenix.home.sessioncontrol.viewholders
|
|
5
|
+package org.mozilla.fenix.tor.view
|
6
|
6
|
|
7
|
7
|
import android.view.View
|
8
|
8
|
import androidx.recyclerview.widget.RecyclerView
|
9
|
9
|
import org.mozilla.fenix.R
|
10
|
|
-import org.mozilla.fenix.databinding.TorBootstrapPagerBinding
|
11
|
10
|
import org.mozilla.fenix.components.Components
|
12
|
|
-import org.mozilla.fenix.home.sessioncontrol.TorBootstrapInteractor
|
13
|
|
-import org.mozilla.fenix.home.sessioncontrol.viewholders.torbootstrap.BootstrapPagerAdapter
|
|
11
|
+import org.mozilla.fenix.databinding.TorBootstrapPagerBinding
|
|
12
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
14
|
13
|
|
15
|
14
|
class TorBootstrapPagerViewHolder(
|
16
|
|
- view: View,
|
17
|
|
- components: Components,
|
18
|
|
- interactor: TorBootstrapInteractor
|
19
|
|
-) : RecyclerView.ViewHolder(view) {
|
|
15
|
+ view: View,
|
|
16
|
+ components: Components,
|
|
17
|
+ interactor: TorBootstrapInteractor
|
|
18
|
+ ) : RecyclerView.ViewHolder(view) {
|
20
|
19
|
|
21
|
|
- private val bootstrapPagerAdapter = BootstrapPagerAdapter(components, interactor)
|
|
20
|
+ private val bootstrapPagerAdapter = TorBootstrapPagerAdapter(components, interactor)
|
22
|
21
|
|
23
|
22
|
init {
|
24
|
23
|
val binding = TorBootstrapPagerBinding.bind(view)
|
fenix/app/src/main/java/org/mozilla/fenix/tor/view/TorBootstrapView.kt
|
1
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+package org.mozilla.fenix.tor.view
|
|
6
|
+
|
|
7
|
+import androidx.lifecycle.LifecycleOwner
|
|
8
|
+import androidx.recyclerview.widget.LinearLayoutManager
|
|
9
|
+import androidx.recyclerview.widget.RecyclerView
|
|
10
|
+import org.mozilla.fenix.components.appstate.AppState
|
|
11
|
+import org.mozilla.fenix.ext.components
|
|
12
|
+import org.mozilla.fenix.tor.interactor.TorBootstrapInteractor
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+class TorBootstrapView(
|
|
16
|
+ containerView: RecyclerView,
|
|
17
|
+ viewLifecycleOwner: LifecycleOwner,
|
|
18
|
+ interactor: TorBootstrapInteractor,
|
|
19
|
+) {
|
|
20
|
+
|
|
21
|
+ val view: RecyclerView = containerView //as RecyclerView
|
|
22
|
+
|
|
23
|
+ private fun bootstrapAdapterItems() = listOf(AdapterItem.TorBootstrap)
|
|
24
|
+
|
|
25
|
+ private val torBootstrapAdapter = TorBootstrapAdapter(
|
|
26
|
+ interactor,
|
|
27
|
+ viewLifecycleOwner,
|
|
28
|
+ containerView.context.components,
|
|
29
|
+ )
|
|
30
|
+
|
|
31
|
+ //private val torBootstrapAdapter =
|
|
32
|
+ // TorBootstrapAdapter(interactor, containerView.context.components)
|
|
33
|
+ //private val torBootstrapAdapter = TorBootstrapPagerAdapter(containerView.context.components, interactor)
|
|
34
|
+
|
|
35
|
+ init {
|
|
36
|
+ containerView.apply {
|
|
37
|
+ adapter = torBootstrapAdapter
|
|
38
|
+ layoutManager = LinearLayoutManager(containerView.context)
|
|
39
|
+ }
|
|
40
|
+ }
|
|
41
|
+
|
|
42
|
+ private fun AppState.toAdapterList(): List<AdapterItem> {
|
|
43
|
+ return bootstrapAdapterItems()
|
|
44
|
+ }
|
|
45
|
+
|
|
46
|
+ fun update(state: AppState) {
|
|
47
|
+ torBootstrapAdapter.submitList(state.toAdapterList())
|
|
48
|
+ }
|
|
49
|
+} |
fenix/app/src/main/res/drawable/tor_onboarding_donate_gradient.xml
deleted
1
|
|
-<?xml version="1.0" encoding="utf-8"?>
|
2
|
|
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
3
|
|
- - License, v. 2.0. If a copy of the MPL was not distributed with this
|
4
|
|
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
5
|
|
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
6
|
|
- <item>
|
7
|
|
- <shape>
|
8
|
|
- <gradient
|
9
|
|
- android:angle="45"
|
10
|
|
- android:startColor="#07d1db"
|
11
|
|
- android:endColor="#b240f5"
|
12
|
|
- android:type="linear" />
|
13
|
|
- </shape>
|
14
|
|
- </item>
|
15
|
|
-</selector> |
fenix/app/src/main/res/drawable/tor_onboarding_donate_rounded_corners.xml
deleted
1
|
|
-<?xml version="1.0" encoding="utf-8"?>
|
2
|
|
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
3
|
|
- - License, v. 2.0. If a copy of the MPL was not distributed with this
|
4
|
|
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
5
|
|
-
|
6
|
|
-<!-- Used for rounding the corners of a button -->
|
7
|
|
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
8
|
|
- android:shape="rectangle">
|
9
|
|
- <solid android:color="#70efde" />
|
10
|
|
- <corners android:radius="10dp" />
|
11
|
|
-</shape> |
fenix/app/src/main/res/layout/tor_onboarding_donate.xml
deleted
1
|
|
-<?xml version="1.0" encoding="utf-8"?>
|
2
|
|
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
3
|
|
- - License, v. 2.0. If a copy of the MPL was not distributed with this
|
4
|
|
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
5
|
|
-<androidx.constraintlayout.widget.ConstraintLayout
|
6
|
|
- xmlns:android="http://schemas.android.com/apk/res/android"
|
7
|
|
- xmlns:app="http://schemas.android.com/apk/res-auto"
|
8
|
|
- xmlns:tools="http://schemas.android.com/tools"
|
9
|
|
- android:id="@+id/onboarding_card"
|
10
|
|
- style="@style/TorOnboardingDonateCardLightWithPadding"
|
11
|
|
- android:layout_width="match_parent"
|
12
|
|
- android:layout_height="wrap_content">
|
13
|
|
- <TextView
|
14
|
|
- android:id="@+id/header_text"
|
15
|
|
- android:layout_width="0dp"
|
16
|
|
- android:layout_height="wrap_content"
|
17
|
|
- android:text="@string/tor_onboarding_donate_header"
|
18
|
|
- android:textAppearance="@style/TorHeaderTextStyle"
|
19
|
|
- android:gravity="center_vertical"
|
20
|
|
- android:lines="1"
|
21
|
|
- app:layout_constraintStart_toStartOf="parent"
|
22
|
|
- app:layout_constraintTop_toTopOf="parent"
|
23
|
|
- app:layout_constraintEnd_toEndOf="parent" />
|
24
|
|
- <TextView
|
25
|
|
- android:id="@+id/description_text"
|
26
|
|
- android:layout_width="match_parent"
|
27
|
|
- android:layout_height="wrap_content"
|
28
|
|
- android:textAppearance="@style/TorBody16TextStyle"
|
29
|
|
- android:layout_marginTop="14dp"
|
30
|
|
- android:text="@string/tor_onboarding_donate_description"
|
31
|
|
- app:layout_constraintTop_toBottomOf="@id/header_text"
|
32
|
|
- app:layout_constraintStart_toStartOf="parent"
|
33
|
|
- app:layout_constraintEnd_toEndOf="parent" />
|
34
|
|
-
|
35
|
|
- <Button
|
36
|
|
- style="@style/TorDonateOnboardingButton"
|
37
|
|
- android:id="@+id/donate_now_button"
|
38
|
|
- android:text="@string/tor_onboarding_donate_button"
|
39
|
|
- android:layout_marginTop="10dp"
|
40
|
|
- android:textAppearance="@style/TorHeaderTextStyle"
|
41
|
|
- android:background="">"@drawable/tor_onboarding_donate_rounded_corners"
|
42
|
|
- app:layout_constraintTop_toBottomOf="@id/description_text"
|
43
|
|
- app:layout_constraintStart_toStartOf="parent"
|
44
|
|
- app:layout_constraintEnd_toEndOf="parent"
|
45
|
|
- app:layout_constraintBottom_toBottomOf="parent"/>
|
46
|
|
-</androidx.constraintlayout.widget.ConstraintLayout> |
fenix/app/src/main/res/layout/tor_onboarding_security_level.xml
deleted
1
|
|
-<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
|
- - License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
|
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
4
|
|
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
5
|
|
- xmlns:app="http://schemas.android.com/apk/res-auto"
|
6
|
|
- xmlns:tools="http://schemas.android.com/tools"
|
7
|
|
- android:id="@+id/onboarding_card"
|
8
|
|
- style="@style/OnboardingCardLightWithPadding"
|
9
|
|
- android:layout_width="match_parent"
|
10
|
|
- android:layout_height="wrap_content"
|
11
|
|
- android:clipChildren="false"
|
12
|
|
- android:clipToPadding="false">
|
13
|
|
-
|
14
|
|
- <TextView
|
15
|
|
- android:id="@+id/header_text"
|
16
|
|
- android:layout_width="0dp"
|
17
|
|
- android:layout_height="wrap_content"
|
18
|
|
- android:drawablePadding="12dp"
|
19
|
|
- android:gravity="center_vertical"
|
20
|
|
- android:lines="1"
|
21
|
|
- android:text="@string/tor_onboarding_security_level"
|
22
|
|
- android:textAppearance="@style/HeaderTextStyle"
|
23
|
|
- app:layout_constraintStart_toStartOf="parent"
|
24
|
|
- app:layout_constraintTop_toTopOf="parent"
|
25
|
|
- tools:drawableStart="@drawable/ic_onboarding_tracking_protection" />
|
26
|
|
-
|
27
|
|
- <TextView
|
28
|
|
- android:id="@+id/description_text"
|
29
|
|
- android:layout_width="match_parent"
|
30
|
|
- android:layout_height="wrap_content"
|
31
|
|
- android:layout_marginTop="12dp"
|
32
|
|
- android:textAppearance="@style/Body14TextStyle"
|
33
|
|
- app:layout_constraintEnd_toEndOf="parent"
|
34
|
|
- app:layout_constraintStart_toStartOf="parent"
|
35
|
|
- app:layout_constraintTop_toBottomOf="@id/current_level"
|
36
|
|
- tools:text="@string/tor_onboarding_security_level_description" />
|
37
|
|
-
|
38
|
|
- <TextView
|
39
|
|
- android:id="@+id/current_level"
|
40
|
|
- android:layout_width="match_parent"
|
41
|
|
- android:layout_height="wrap_content"
|
42
|
|
- android:layout_marginTop="12dp"
|
43
|
|
- app:layout_constraintEnd_toEndOf="parent"
|
44
|
|
- app:layout_constraintStart_toStartOf="parent"
|
45
|
|
- app:layout_constraintTop_toBottomOf="@id/header_text"
|
46
|
|
- tools:text="@string/tor_onboarding_chosen_security_level_label" />
|
47
|
|
-
|
48
|
|
- <org.mozilla.fenix.onboarding.OnboardingRadioButton
|
49
|
|
- android:id="@+id/security_level_standard_option"
|
50
|
|
- android:layout_width="match_parent"
|
51
|
|
- android:layout_height="wrap_content"
|
52
|
|
- android:layout_marginStart="16dp"
|
53
|
|
- android:layout_marginTop="16dp"
|
54
|
|
- android:layout_marginBottom="16dp"
|
55
|
|
- android:background="">"@android:color/transparent"
|
56
|
|
- android:checked="true"
|
57
|
|
- android:foreground="@drawable/rounded_ripple"
|
58
|
|
- android:gravity="top"
|
59
|
|
- android:paddingStart="8dp"
|
60
|
|
- android:paddingEnd="8dp"
|
61
|
|
- android:theme="@style/Checkable.Colored"
|
62
|
|
- app:layout_constraintStart_toStartOf="parent"
|
63
|
|
- app:layout_constraintTop_toBottomOf="@id/description_text"
|
64
|
|
- app:_onboardingKey_="@string/pref_key_tor_security_level_standard_option"
|
65
|
|
- app:_onboardingKeyDescription_="@string/tor_security_level_standard_description"
|
66
|
|
- app:_onboardingKeyTitle_="@string/tor_security_level_standard_option"
|
67
|
|
- tools:text="Standard" />
|
68
|
|
-
|
69
|
|
- <org.mozilla.fenix.onboarding.OnboardingRadioButton
|
70
|
|
- android:id="@+id/security_level_safer_option"
|
71
|
|
- android:layout_width="match_parent"
|
72
|
|
- android:layout_height="wrap_content"
|
73
|
|
- android:layout_marginStart="16dp"
|
74
|
|
- android:layout_marginTop="16dp"
|
75
|
|
- android:layout_marginBottom="16dp"
|
76
|
|
- android:background="">"@android:color/transparent"
|
77
|
|
- android:checked="false"
|
78
|
|
- android:foreground="@drawable/rounded_ripple"
|
79
|
|
- android:gravity="top"
|
80
|
|
- android:paddingStart="8dp"
|
81
|
|
- android:paddingEnd="8dp"
|
82
|
|
- android:textColor="@color/primary_state_list_text_color"
|
83
|
|
- android:theme="@style/Checkable.Colored"
|
84
|
|
- app:layout_constraintStart_toStartOf="parent"
|
85
|
|
- app:layout_constraintTop_toBottomOf="@id/security_level_standard_option"
|
86
|
|
- app:_onboardingKey_="@string/pref_key_tor_security_level_safer_option"
|
87
|
|
- app:_onboardingKeyDescription_="@string/tor_security_level_safer_description"
|
88
|
|
- app:_onboardingKeyTitle_="@string/tor_security_level_safer_option"
|
89
|
|
- tools:text="Safer" />
|
90
|
|
-
|
91
|
|
- <org.mozilla.fenix.onboarding.OnboardingRadioButton
|
92
|
|
- android:id="@+id/security_level_safest_option"
|
93
|
|
- android:layout_width="match_parent"
|
94
|
|
- android:layout_height="wrap_content"
|
95
|
|
- android:layout_marginStart="16dp"
|
96
|
|
- android:layout_marginTop="16dp"
|
97
|
|
- android:layout_marginBottom="16dp"
|
98
|
|
- android:background="">"@android:color/transparent"
|
99
|
|
- android:checked="false"
|
100
|
|
- android:foreground="@drawable/rounded_ripple"
|
101
|
|
- android:gravity="top"
|
102
|
|
- android:paddingStart="8dp"
|
103
|
|
- android:paddingEnd="8dp"
|
104
|
|
- android:textColor="@color/primary_state_list_text_color"
|
105
|
|
- android:theme="@style/Checkable.Colored"
|
106
|
|
- app:layout_constraintStart_toStartOf="parent"
|
107
|
|
- app:layout_constraintTop_toBottomOf="@id/security_level_safer_option"
|
108
|
|
- app:_onboardingKey_="@string/pref_key_tor_security_level_safest_option"
|
109
|
|
- app:_onboardingKeyDescription_="@string/tor_security_level_safest_description"
|
110
|
|
- app:_onboardingKeyTitle_="@string/tor_security_level_safest_option"
|
111
|
|
- tools:text="Safest" />
|
112
|
|
-
|
113
|
|
- <Button
|
114
|
|
- android:id="@+id/open_settings_button"
|
115
|
|
- style="@style/NeutralOnboardingButton"
|
116
|
|
- android:layout_marginTop="16dp"
|
117
|
|
- android:text="@string/tor_onboarding_security_settings_button"
|
118
|
|
- app:layout_constraintTop_toBottomOf="@id/security_level_safest_option"
|
119
|
|
- app:layout_constraintStart_toStartOf="parent"
|
120
|
|
- app:layout_constraintEnd_toEndOf="parent"
|
121
|
|
- app:layout_constraintBottom_toBottomOf="parent"/>
|
122
|
|
-
|
123
|
|
-</androidx.constraintlayout.widget.ConstraintLayout> |
fenix/app/src/main/res/navigation/nav_graph.xml
... |
... |
@@ -21,6 +21,12 @@ |
21
|
21
|
app:popUpTo="@id/startupFragment"
|
22
|
22
|
app:popUpToInclusive="true" />
|
23
|
23
|
|
|
24
|
+ <action
|
|
25
|
+ android:id="@+id/action_startup_torbootstrap"
|
|
26
|
+ app:destination="@id/torbootstrapFragment"
|
|
27
|
+ app:popUpTo="@id/startupFragment"
|
|
28
|
+ app:popUpToInclusive="true" />
|
|
29
|
+
|
24
|
30
|
<action
|
25
|
31
|
android:id="@+id/action_global_home"
|
26
|
32
|
app:destination="@id/homeFragment"
|
... |
... |
@@ -247,6 +253,24 @@ |
247
|
253
|
app:popUpToInclusive="true" />
|
248
|
254
|
</fragment>
|
249
|
255
|
|
|
256
|
+ <fragment
|
|
257
|
+ android:id="@+id/torbootstrapFragment"
|
|
258
|
+ android:name="org.mozilla.fenix.tor.TorBootstrapFragment"
|
|
259
|
+ tools:layout="@layout/fragment_home">
|
|
260
|
+ <action
|
|
261
|
+ android:id="@+id/action_home"
|
|
262
|
+ app:destination="@id/homeFragment"
|
|
263
|
+ app:popUpTo="@id/torbootstrapFragment"
|
|
264
|
+ app:popUpToInclusive="true" />
|
|
265
|
+ <action
|
|
266
|
+ android:id="@+id/action_torbootstrapFragment_to_torNetworkSettingsFragment"
|
|
267
|
+ app:destination="@id/torNetworkSettingsFragment"
|
|
268
|
+ app:enterAnim="@anim/slide_in_right"
|
|
269
|
+ app:exitAnim="@anim/slide_out_left"
|
|
270
|
+ app:popEnterAnim="@anim/slide_in_left"
|
|
271
|
+ app:popExitAnim="@anim/slide_out_right" />
|
|
272
|
+ </fragment>
|
|
273
|
+
|
250
|
274
|
<dialog
|
251
|
275
|
android:id="@+id/homeOnboardingDialogFragment"
|
252
|
276
|
android:name="org.mozilla.fenix.onboarding.HomeOnboardingDialogFragment" />
|
fenix/app/src/main/res/values/styles.xml
... |
... |
@@ -375,13 +375,6 @@ |
375
|
375
|
<item name="android:textColor">?attr/textPrimary</item>
|
376
|
376
|
</style>
|
377
|
377
|
|
378
|
|
- <!-- Ideally we should consolidate this with NeutralButton in the future -->
|
379
|
|
- <style name="TorDonateOnboardingButton" parent="NeutralButton">
|
380
|
|
- <item name="android:background">@drawable/tor_onboarding_donate_rounded_corners</item>
|
381
|
|
- <item name="backgroundTint">#70efde</item>
|
382
|
|
- <item name="android:textColor">#000000</item>
|
383
|
|
- </style>
|
384
|
|
-
|
385
|
378
|
<style name="DestructiveButton" parent="NeutralButton">
|
386
|
379
|
<item name="iconTint">@color/fx_mobile_icon_color_warning_button</item>
|
387
|
380
|
<item name="android:textColor">@color/fx_mobile_text_color_warning_button</item>
|
... |
... |
@@ -582,10 +575,6 @@ |
582
|
575
|
<item name="android:elevation">0dp</item>
|
583
|
576
|
</style>
|
584
|
577
|
|
585
|
|
- <style name="TorOnboardingDonateCardLightWithPadding" parent="OnboardingCardDark">
|
586
|
|
- <item name="android:background">@drawable/tor_onboarding_donate_gradient</item>
|
587
|
|
- </style>
|
588
|
|
-
|
589
|
578
|
<style name="SearchClipboardStyle">
|
590
|
579
|
<item name="android:ellipsize">end</item>
|
591
|
580
|
<item name="android:maxLines">1</item>
|
|