16900 make navgraph inflation asynchronous (#18889)
* For #16900: implement async navgraph inflation For #16900: removed nav graph from xml For #16900: inflate navGraph programatically For #16900: Made NavGraph inflation asynchronous For #16900: Changed to block with runBlocking For #16900: Refactored blocking call into a function For 16900: NavGraph inflation is now async We now attach the nav graph (or check if its attached) on every nav call ( an extension function for NavController). This is done by checking the value of the job stored in PerfNavController.map which keeps track of the job with the NavController as a Key. If the job hasn't been completed, it will block the main thread until the job is done. The job itself is responsible for attaching the navgraph to the navcontroller (and the inflation of the latter too) For 16900: rebased upstream master For 16900: Rebase on master For #16900: Fixed Async Navgraph navigation per review comments. 1)The Asynchronous method is now found in NavGraphProvider.kt. It creates a job on the IO dispatcher 2)The Job is tracked through a WeakHashMap from Controller --> NavGraph 3)The Coroutine scope doesn't use MainScope() anymore 4)The Coroutine is cancelled if the Activity is destroyed 5)The tests mockk the blockForNavGraphInflation method through the FenixReoboelectricTestApplication instead of calling the mock every setup() For #16900: inflateNavGraphAsync now takes navController For #16900: Pass lifecycleScope to NavGraphProvider For #16900: removed unused mock For #16900: Added linter rules for navigate calls We need linting rules to make sure no one calls the NavController.navigate() methods For #16900: Added TestRule to help abstract the mocks in the code For 16900: Fix linting problems For #16900: Cleaned duplicated code in tests For #16900: cleaned up NavGraphTestRule for finished test For #16900: had to revert an accidentally edited file For #16900: rebased master * For #16900: Review nits for async navgraph This is composed of squash commits, the original messages can be found below: -> DisableNavGraphProviderAssertionRule + kdoc. Use test rule in RobolectricApplication. Fix failing CrashReporterControllerTest Fix blame by -> navigate in tests. This commit was generated by the following commands only: ``` find app/src/test -type f -exec sed -i '' "/import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph/d" {} \; find app/src/test -type f -exec sed -i "" "s/navigateBlockingForAsyncNavGraph/navigate/g" {} \; git checkout app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker ``` Fix various blame This is expected to be squashed into the first commit so, if so, it'd fix the blame. Move test rule to helpers pkg. add missing license header Add import change I missed fix unused imports Replace robolectricTestrunner with test rule. Improve navGraphProvider docs Remove unnecessary rule as defined by robolectric. add clarifying comment to robolectric remove unnecessary space * For #16900: nit fixes for MozillaNavigateCheck and lint fixes 3 squash commits: *Changed violation message and fixed the lint rule for MozillaNavigateCheck *Added suppression to NavController.kt *Fixed detekt violations * For 16900: Fixed failing tests Co-authored-by: Michael Comella <michael.l.comella@gmail.com>
This commit is contained in:
parent
973c891c5e
commit
990bfa7e6d
|
@ -21,7 +21,7 @@ import org.mozilla.fenix.helpers.HomeActivityTestRule
|
||||||
|
|
||||||
// BEFORE INCREASING THESE VALUES, PLEASE CONSULT WITH THE PERF TEAM.
|
// BEFORE INCREASING THESE VALUES, PLEASE CONSULT WITH THE PERF TEAM.
|
||||||
private const val EXPECTED_SUPPRESSION_COUNT = 11
|
private const val EXPECTED_SUPPRESSION_COUNT = 11
|
||||||
private const val EXPECTED_RUNBLOCKING_COUNT = 2
|
private const val EXPECTED_RUNBLOCKING_COUNT = 3
|
||||||
private const val EXPECTED_COMPONENT_INIT_COUNT = 42
|
private const val EXPECTED_COMPONENT_INIT_COUNT = 42
|
||||||
private const val EXPECTED_VIEW_HIERARCHY_DEPTH = 12
|
private const val EXPECTED_VIEW_HIERARCHY_DEPTH = 12
|
||||||
private const val EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN = 4
|
private const val EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN = 4
|
||||||
|
|
|
@ -15,6 +15,7 @@ import mozilla.components.concept.engine.request.RequestInterceptor
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.isOnline
|
import org.mozilla.fenix.ext.isOnline
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
class AppRequestInterceptor(
|
class AppRequestInterceptor(
|
||||||
|
@ -97,7 +98,7 @@ class AppRequestInterceptor(
|
||||||
|
|
||||||
// Navigate and trigger add-on installation.
|
// Navigate and trigger add-on installation.
|
||||||
matchResult.groupValues.getOrNull(1)?.let { addonId ->
|
matchResult.groupValues.getOrNull(1)?.let { addonId ->
|
||||||
navController?.get()?.navigate(
|
navController?.get()?.navigateBlockingForAsyncNavGraph(
|
||||||
NavGraphDirections.actionGlobalAddonsManagementFragment(addonId)
|
NavGraphDirections.actionGlobalAddonsManagementFragment(addonId)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,12 @@ import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.NavigationUI
|
import androidx.navigation.ui.NavigationUI
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import mozilla.appservices.places.BookmarkRoot
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
import mozilla.components.browser.state.action.ContentAction
|
import mozilla.components.browser.state.action.ContentAction
|
||||||
import mozilla.components.browser.state.search.SearchEngine
|
import mozilla.components.browser.state.search.SearchEngine
|
||||||
|
@ -79,6 +79,7 @@ import org.mozilla.fenix.exceptions.trackingprotection.TrackingProtectionExcepti
|
||||||
import org.mozilla.fenix.ext.alreadyOnDestination
|
import org.mozilla.fenix.ext.alreadyOnDestination
|
||||||
import org.mozilla.fenix.ext.breadcrumb
|
import org.mozilla.fenix.ext.breadcrumb
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.measureNoInline
|
import org.mozilla.fenix.ext.measureNoInline
|
||||||
import org.mozilla.fenix.ext.metrics
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
|
@ -94,6 +95,7 @@ import org.mozilla.fenix.library.bookmarks.BookmarkFragmentDirections
|
||||||
import org.mozilla.fenix.library.bookmarks.DesktopFolders
|
import org.mozilla.fenix.library.bookmarks.DesktopFolders
|
||||||
import org.mozilla.fenix.library.history.HistoryFragmentDirections
|
import org.mozilla.fenix.library.history.HistoryFragmentDirections
|
||||||
import org.mozilla.fenix.library.recentlyclosed.RecentlyClosedFragmentDirections
|
import org.mozilla.fenix.library.recentlyclosed.RecentlyClosedFragmentDirections
|
||||||
|
import org.mozilla.fenix.perf.NavGraphProvider
|
||||||
import org.mozilla.fenix.perf.Performance
|
import org.mozilla.fenix.perf.Performance
|
||||||
import org.mozilla.fenix.perf.PerformanceInflater
|
import org.mozilla.fenix.perf.PerformanceInflater
|
||||||
import org.mozilla.fenix.perf.ProfilerMarkers
|
import org.mozilla.fenix.perf.ProfilerMarkers
|
||||||
|
@ -131,7 +133,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
// components requires context to access.
|
// components requires context to access.
|
||||||
protected val homeActivityInitTimeStampNanoSeconds = SystemClock.elapsedRealtimeNanos()
|
protected val homeActivityInitTimeStampNanoSeconds = SystemClock.elapsedRealtimeNanos()
|
||||||
|
|
||||||
private var webExtScope: CoroutineScope? = null
|
|
||||||
lateinit var themeManager: ThemeManager
|
lateinit var themeManager: ThemeManager
|
||||||
lateinit var browsingModeManager: BrowsingModeManager
|
lateinit var browsingModeManager: BrowsingModeManager
|
||||||
|
|
||||||
|
@ -193,7 +194,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
components.publicSuffixList.prefetch()
|
components.publicSuffixList.prefetch()
|
||||||
|
|
||||||
setupThemeAndBrowsingMode(getModeFromIntentOrLastKnown(intent))
|
setupThemeAndBrowsingMode(getModeFromIntentOrLastKnown(intent))
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home).run {
|
||||||
|
// Do not call anything between setContentView and inflateNavGraphAsync.
|
||||||
|
// It needs to start its job as early as possible.
|
||||||
|
NavGraphProvider.inflateNavGraphAsync(navHost.navController, lifecycleScope)
|
||||||
|
}
|
||||||
|
|
||||||
// Must be after we set the content view
|
// Must be after we set the content view
|
||||||
if (isVisuallyComplete) {
|
if (isVisuallyComplete) {
|
||||||
|
@ -934,7 +939,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
webExtensionId = webExtensionState.id,
|
webExtensionId = webExtensionState.id,
|
||||||
webExtensionTitle = webExtensionState.name
|
webExtensionTitle = webExtensionState.name
|
||||||
)
|
)
|
||||||
navHost.navController.navigate(action)
|
navHost.navController.navigateBlockingForAsyncNavGraph(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,6 +8,7 @@ import androidx.navigation.NavController
|
||||||
import mozilla.components.feature.addons.Addon
|
import mozilla.components.feature.addons.Addon
|
||||||
import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate
|
import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.navigateSafe
|
import org.mozilla.fenix.ext.navigateSafe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,6 +56,6 @@ class AddonsManagementView(
|
||||||
AddonsManagementFragmentDirections.actionAddonsManagementFragmentToNotYetSupportedAddonFragment(
|
AddonsManagementFragmentDirections.actionAddonsManagementFragmentToNotYetSupportedAddonFragment(
|
||||||
unsupportedAddons.toTypedArray()
|
unsupportedAddons.toTypedArray()
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ class InstalledAddonDetailsFragment : Fragment() {
|
||||||
InstalledAddonDetailsFragmentDirections
|
InstalledAddonDetailsFragmentDirections
|
||||||
.actionInstalledAddonFragmentToAddonInternalSettingsFragment(addon)
|
.actionInstalledAddonFragmentToAddonInternalSettingsFragment(addon)
|
||||||
}
|
}
|
||||||
Navigation.findNavController(this).navigate(directions)
|
Navigation.findNavController(this).navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +227,7 @@ class InstalledAddonDetailsFragment : Fragment() {
|
||||||
InstalledAddonDetailsFragmentDirections.actionInstalledAddonFragmentToAddonDetailsFragment(
|
InstalledAddonDetailsFragmentDirections.actionInstalledAddonFragmentToAddonDetailsFragment(
|
||||||
addon
|
addon
|
||||||
)
|
)
|
||||||
Navigation.findNavController(view).navigate(directions)
|
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +237,7 @@ class InstalledAddonDetailsFragment : Fragment() {
|
||||||
InstalledAddonDetailsFragmentDirections.actionInstalledAddonFragmentToAddonPermissionsDetailsFragment(
|
InstalledAddonDetailsFragmentDirections.actionInstalledAddonFragmentToAddonPermissionsDetailsFragment(
|
||||||
addon
|
addon
|
||||||
)
|
)
|
||||||
Navigation.findNavController(view).navigate(directions)
|
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,7 @@ import java.lang.ref.WeakReference
|
||||||
import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior
|
import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior
|
||||||
import mozilla.components.feature.webauthn.WebAuthnFeature
|
import mozilla.components.feature.webauthn.WebAuthnFeature
|
||||||
import mozilla.components.support.base.feature.ActivityResultHandler
|
import mozilla.components.support.base.feature.ActivityResultHandler
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import mozilla.components.support.ktx.android.view.enterToImmersiveMode
|
import mozilla.components.support.ktx.android.view.enterToImmersiveMode
|
||||||
import org.mozilla.fenix.GleanMetrics.PerfStartup
|
import org.mozilla.fenix.GleanMetrics.PerfStartup
|
||||||
import org.mozilla.fenix.ext.measureNoInline
|
import org.mozilla.fenix.ext.measureNoInline
|
||||||
|
@ -557,7 +558,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
|
||||||
showPage = true,
|
showPage = true,
|
||||||
sessionId = getCurrentTab()?.id
|
sessionId = getCurrentTab()?.id
|
||||||
)
|
)
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onNeedToRequestPermissions = { permissions ->
|
onNeedToRequestPermissions = { permissions ->
|
||||||
|
@ -568,7 +569,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
|
||||||
browserAnimator.captureEngineViewAndDrawStatically {
|
browserAnimator.captureEngineViewAndDrawStatically {
|
||||||
val directions =
|
val directions =
|
||||||
NavGraphDirections.actionGlobalSavedLoginsAuthFragment()
|
NavGraphDirections.actionGlobalSavedLoginsAuthFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -979,7 +980,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackLongPressed(): Boolean {
|
override fun onBackLongPressed(): Boolean {
|
||||||
findNavController().navigate(
|
findNavController().navigateBlockingForAsyncNavGraph(
|
||||||
NavGraphDirections.actionGlobalTabHistoryDialogFragment(
|
NavGraphDirections.actionGlobalTabHistoryDialogFragment(
|
||||||
activeSessionId = customTabSessionId
|
activeSessionId = customTabSessionId
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.components.TabCollectionStorage
|
import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.navigateSafe
|
import org.mozilla.fenix.ext.navigateSafe
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
@ -264,7 +265,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
|
||||||
)
|
)
|
||||||
.setText(view.context.getString(messageStringRes))
|
.setText(view.context.getString(messageStringRes))
|
||||||
.setAction(requireContext().getString(R.string.create_collection_view)) {
|
.setAction(requireContext().getString(R.string.create_collection_view)) {
|
||||||
findNavController().navigate(
|
findNavController().navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = false)
|
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.mozilla.fenix.browser.readermode.ReaderModeController
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.home.HomeScreenViewModel
|
import org.mozilla.fenix.home.HomeScreenViewModel
|
||||||
|
@ -118,7 +119,7 @@ class DefaultBrowserToolbarController(
|
||||||
// When closing the last tab we must show the undo snackbar in the home fragment
|
// When closing the last tab we must show the undo snackbar in the home fragment
|
||||||
if (store.state.getNormalOrPrivateTabs(it.content.private).count() == 1) {
|
if (store.state.getNormalOrPrivateTabs(it.content.private).count() == 1) {
|
||||||
homeViewModel.sessionToDelete = it.id
|
homeViewModel.sessionToDelete = it.id
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalHome()
|
BrowserFragmentDirections.actionGlobalHome()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -132,7 +133,7 @@ class DefaultBrowserToolbarController(
|
||||||
Event.TabCounterMenuItemTapped(Event.TabCounterMenuItemTapped.Item.NEW_TAB)
|
Event.TabCounterMenuItemTapped(Event.TabCounterMenuItemTapped.Item.NEW_TAB)
|
||||||
)
|
)
|
||||||
activity.browsingModeManager.mode = BrowsingMode.Normal
|
activity.browsingModeManager.mode = BrowsingMode.Normal
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
|
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -143,7 +144,7 @@ class DefaultBrowserToolbarController(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
activity.browsingModeManager.mode = BrowsingMode.Private
|
activity.browsingModeManager.mode = BrowsingMode.Private
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
|
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.getRootView
|
import org.mozilla.fenix.ext.getRootView
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.navigateSafe
|
import org.mozilla.fenix.ext.navigateSafe
|
||||||
import org.mozilla.fenix.ext.openSetDefaultBrowserOption
|
import org.mozilla.fenix.ext.openSetDefaultBrowserOption
|
||||||
|
@ -162,7 +163,7 @@ class DefaultBrowserToolbarMenuController(
|
||||||
}
|
}
|
||||||
is ToolbarMenu.Item.Back -> {
|
is ToolbarMenu.Item.Back -> {
|
||||||
if (item.viewHistory) {
|
if (item.viewHistory) {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
|
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
|
||||||
activeSessionId = customTabSessionId
|
activeSessionId = customTabSessionId
|
||||||
)
|
)
|
||||||
|
@ -175,7 +176,7 @@ class DefaultBrowserToolbarMenuController(
|
||||||
}
|
}
|
||||||
is ToolbarMenu.Item.Forward -> {
|
is ToolbarMenu.Item.Forward -> {
|
||||||
if (item.viewHistory) {
|
if (item.viewHistory) {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
|
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
|
||||||
activeSessionId = customTabSessionId
|
activeSessionId = customTabSessionId
|
||||||
)
|
)
|
||||||
|
@ -212,7 +213,7 @@ class DefaultBrowserToolbarMenuController(
|
||||||
),
|
),
|
||||||
showPage = true
|
showPage = true
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
is ToolbarMenu.Item.Settings -> browserAnimator.captureEngineViewAndDrawStatically {
|
is ToolbarMenu.Item.Settings -> browserAnimator.captureEngineViewAndDrawStatically {
|
||||||
val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment()
|
val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment()
|
||||||
|
@ -341,7 +342,7 @@ class DefaultBrowserToolbarMenuController(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ToolbarMenu.Item.NewTab -> {
|
is ToolbarMenu.Item.NewTab -> {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
|
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
// We suppress the calls to `navigate` since we invoke the Android `NavController.navigate` through
|
||||||
|
// this file. Detekt checks for the `navigate()` function calls, which should be ignored in this file.
|
||||||
|
@file:Suppress("MozillaNavigateCheck")
|
||||||
package org.mozilla.fenix.ext
|
package org.mozilla.fenix.ext
|
||||||
|
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
|
@ -10,12 +13,15 @@ import androidx.navigation.NavDirections
|
||||||
import androidx.navigation.NavOptions
|
import androidx.navigation.NavOptions
|
||||||
import io.sentry.Sentry
|
import io.sentry.Sentry
|
||||||
import org.mozilla.fenix.components.isSentryEnabled
|
import org.mozilla.fenix.components.isSentryEnabled
|
||||||
|
import org.mozilla.fenix.perf.NavGraphProvider
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigate from the fragment with [id] using the given [directions].
|
* Navigate from the fragment with [id] using the given [directions].
|
||||||
* If the id doesn't match the current destination, an error is recorded.
|
* If the id doesn't match the current destination, an error is recorded.
|
||||||
*/
|
*/
|
||||||
fun NavController.nav(@IdRes id: Int?, directions: NavDirections, navOptions: NavOptions? = null) {
|
fun NavController.nav(@IdRes id: Int?, directions: NavDirections, navOptions: NavOptions? = null) {
|
||||||
|
NavGraphProvider.blockForNavGraphInflation(this)
|
||||||
|
|
||||||
if (id == null || this.currentDestination?.id == id) {
|
if (id == null || this.currentDestination?.id == id) {
|
||||||
this.navigate(directions, navOptions)
|
this.navigate(directions, navOptions)
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,6 +29,21 @@ fun NavController.nav(@IdRes id: Int?, directions: NavDirections, navOptions: Na
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun NavController.navigateBlockingForAsyncNavGraph(resId: Int) {
|
||||||
|
NavGraphProvider.blockForNavGraphInflation(this)
|
||||||
|
this.navigate(resId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun NavController.navigateBlockingForAsyncNavGraph(directions: NavDirections) {
|
||||||
|
NavGraphProvider.blockForNavGraphInflation(this)
|
||||||
|
this.navigate(directions)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun NavController.navigateBlockingForAsyncNavGraph(directions: NavDirections, navOptions: NavOptions?) {
|
||||||
|
NavGraphProvider.blockForNavGraphInflation(this)
|
||||||
|
this.navigate(directions, navOptions)
|
||||||
|
}
|
||||||
|
|
||||||
fun NavController.alreadyOnDestination(@IdRes destId: Int?): Boolean {
|
fun NavController.alreadyOnDestination(@IdRes destId: Int?): Boolean {
|
||||||
return destId?.let { currentDestination?.id == it || popBackStack(it, false) } ?: false
|
return destId?.let { currentDestination?.id == it || popBackStack(it, false) } ?: false
|
||||||
}
|
}
|
||||||
|
@ -38,6 +59,6 @@ fun NavController.navigateSafe(
|
||||||
directions: NavDirections
|
directions: NavDirections
|
||||||
) {
|
) {
|
||||||
if (currentDestination?.id == resId) {
|
if (currentDestination?.id == resId) {
|
||||||
this.navigate(directions)
|
this.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu
|
||||||
import org.mozilla.fenix.components.toolbar.ToolbarPosition
|
import org.mozilla.fenix.components.toolbar.ToolbarPosition
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.hideToolbar
|
import org.mozilla.fenix.ext.hideToolbar
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.measureNoInline
|
import org.mozilla.fenix.ext.measureNoInline
|
||||||
import org.mozilla.fenix.ext.metrics
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
|
@ -533,7 +534,7 @@ class HomeFragment : Fragment() {
|
||||||
requireContext().getString(R.string.snackbar_deleted_undo),
|
requireContext().getString(R.string.snackbar_deleted_undo),
|
||||||
{
|
{
|
||||||
requireComponents.useCases.tabsUseCases.undo.invoke()
|
requireComponents.useCases.tabsUseCases.undo.invoke()
|
||||||
findNavController().navigate(
|
findNavController().navigateBlockingForAsyncNavGraph(
|
||||||
HomeFragmentDirections.actionGlobalBrowser(null)
|
HomeFragmentDirections.actionGlobalBrowser(null)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -624,7 +625,8 @@ class HomeFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navToSavedLogins() {
|
private fun navToSavedLogins() {
|
||||||
findNavController().navigate(HomeFragmentDirections.actionGlobalSavedLoginsAuthFragment())
|
findNavController().navigateBlockingForAsyncNavGraph(
|
||||||
|
HomeFragmentDirections.actionGlobalSavedLoginsAuthFragment())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dispatchModeChanges(mode: Mode) {
|
private fun dispatchModeChanges(mode: Mode) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.content.Intent
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import mozilla.components.lib.crash.Crash
|
import mozilla.components.lib.crash.Crash
|
||||||
import org.mozilla.fenix.NavGraphDirections
|
import org.mozilla.fenix.NavGraphDirections
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the app crashes, the user has the option to report it.
|
* When the app crashes, the user has the option to report it.
|
||||||
|
@ -26,6 +27,6 @@ class CrashReporterIntentProcessor : HomeIntentProcessor {
|
||||||
|
|
||||||
private fun openToCrashReporter(intent: Intent, navController: NavController) {
|
private fun openToCrashReporter(intent: Intent, navController: NavController) {
|
||||||
val directions = NavGraphDirections.actionGlobalCrashReporter(intent)
|
val directions = NavGraphDirections.actionGlobalCrashReporter(intent)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
import org.mozilla.fenix.components.SearchWidgetCreator
|
import org.mozilla.fenix.components.SearchWidgetCreator
|
||||||
import org.mozilla.fenix.ext.alreadyOnDestination
|
import org.mozilla.fenix.ext.alreadyOnDestination
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor.DeepLinkVerifier
|
import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor.DeepLinkVerifier
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ class DeepLinkIntentProcessor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!navController.alreadyOnDestination(globalDirections.destinationId)) {
|
if (!navController.alreadyOnDestination(globalDirections.destinationId)) {
|
||||||
navController.navigate(globalDirections.navDirections)
|
navController.navigateBlockingForAsyncNavGraph(globalDirections.navDirections)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import kotlinx.android.synthetic.main.onboarding_manual_signin.view.*
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.home.HomeFragmentDirections
|
import org.mozilla.fenix.home.HomeFragmentDirections
|
||||||
|
|
||||||
class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
@ -22,7 +23,7 @@ class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(vie
|
||||||
it.context.components.analytics.metrics.track(Event.OnboardingManualSignIn)
|
it.context.components.analytics.metrics.track(Event.OnboardingManualSignIn)
|
||||||
|
|
||||||
val directions = HomeFragmentDirections.actionGlobalTurnOnSync()
|
val directions = HomeFragmentDirections.actionGlobalTurnOnSync()
|
||||||
Navigation.findNavController(view).navigate(directions)
|
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ class DefaultBookmarkController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleBookmarkEdit(node: BookmarkNode) {
|
override fun handleBookmarkEdit(node: BookmarkNode) {
|
||||||
navigate(BookmarkFragmentDirections.actionBookmarkFragmentToBookmarkEditFragment(node.guid))
|
navigateToGivenDirection(BookmarkFragmentDirections.actionBookmarkFragmentToBookmarkEditFragment(node.guid))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleBookmarkSelected(node: BookmarkNode) {
|
override fun handleBookmarkSelected(node: BookmarkNode) {
|
||||||
|
@ -118,7 +118,7 @@ class DefaultBookmarkController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleBookmarkSharing(item: BookmarkNode) {
|
override fun handleBookmarkSharing(item: BookmarkNode) {
|
||||||
navigate(
|
navigateToGivenDirection(
|
||||||
BookmarkFragmentDirections.actionGlobalShareFragment(
|
BookmarkFragmentDirections.actionGlobalShareFragment(
|
||||||
data = arrayOf(ShareData(url = item.url, title = item.title))
|
data = arrayOf(ShareData(url = item.url, title = item.title))
|
||||||
)
|
)
|
||||||
|
@ -182,7 +182,7 @@ class DefaultBookmarkController(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigate(directions: NavDirections) {
|
private fun navigateToGivenDirection(directions: NavDirections) {
|
||||||
invokePendingDeletion.invoke()
|
invokePendingDeletion.invoke()
|
||||||
navController.nav(R.id.bookmarkFragment, directions)
|
navController.nav(R.id.bookmarkFragment, directions)
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,7 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.add_bookmark_folder -> {
|
R.id.add_bookmark_folder -> {
|
||||||
navigate(
|
navigateToBookmarkFragment(
|
||||||
BookmarkFragmentDirections
|
BookmarkFragmentDirections
|
||||||
.actionBookmarkFragmentToBookmarkAddFolderFragment()
|
.actionBookmarkFragmentToBookmarkAddFolderFragment()
|
||||||
)
|
)
|
||||||
|
@ -226,7 +226,7 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
||||||
val shareTabs = bookmarkStore.state.mode.selectedItems.map {
|
val shareTabs = bookmarkStore.state.mode.selectedItems.map {
|
||||||
ShareData(url = it.url, title = it.title)
|
ShareData(url = it.url, title = it.title)
|
||||||
}
|
}
|
||||||
navigate(
|
navigateToBookmarkFragment(
|
||||||
BookmarkFragmentDirections.actionGlobalShareFragment(
|
BookmarkFragmentDirections.actionGlobalShareFragment(
|
||||||
data = shareTabs.toTypedArray()
|
data = shareTabs.toTypedArray()
|
||||||
)
|
)
|
||||||
|
@ -243,10 +243,10 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
|
||||||
|
|
||||||
private fun showTabTray() {
|
private fun showTabTray() {
|
||||||
invokePendingDeletion()
|
invokePendingDeletion()
|
||||||
navigate(BookmarkFragmentDirections.actionGlobalTabTrayDialogFragment())
|
navigateToBookmarkFragment(BookmarkFragmentDirections.actionGlobalTabTrayDialogFragment())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigate(directions: NavDirections) {
|
private fun navigateToBookmarkFragment(directions: NavDirections) {
|
||||||
invokePendingDeletion()
|
invokePendingDeletion()
|
||||||
findNavController().nav(
|
findNavController().nav(
|
||||||
R.id.bookmarkFragment,
|
R.id.bookmarkFragment,
|
||||||
|
|
|
@ -15,6 +15,7 @@ import mozilla.components.concept.storage.BookmarkNode
|
||||||
import mozilla.components.support.base.feature.UserInteractionHandler
|
import mozilla.components.support.base.feature.UserInteractionHandler
|
||||||
import org.mozilla.fenix.NavGraphDirections
|
import org.mozilla.fenix.NavGraphDirections
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.library.LibraryPageView
|
import org.mozilla.fenix.library.LibraryPageView
|
||||||
import org.mozilla.fenix.selection.SelectionInteractor
|
import org.mozilla.fenix.selection.SelectionInteractor
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ class BookmarkView(
|
||||||
adapter = bookmarkAdapter
|
adapter = bookmarkAdapter
|
||||||
}
|
}
|
||||||
view.bookmark_folders_sign_in.setOnClickListener {
|
view.bookmark_folders_sign_in.setOnClickListener {
|
||||||
navController.navigate(NavGraphDirections.actionGlobalTurnOnSync())
|
navController.navigateBlockingForAsyncNavGraph(NavGraphDirections.actionGlobalTurnOnSync())
|
||||||
}
|
}
|
||||||
view.swipe_refresh.setOnRefreshListener {
|
view.swipe_refresh.setOnRefreshListener {
|
||||||
interactor.onRequestSync()
|
interactor.onRequestSync()
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
|
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
interface HistoryController {
|
interface HistoryController {
|
||||||
|
@ -94,7 +95,7 @@ class DefaultHistoryController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleShare(item: HistoryItem) {
|
override fun handleShare(item: HistoryItem) {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
HistoryFragmentDirections.actionGlobalShareFragment(
|
HistoryFragmentDirections.actionGlobalShareFragment(
|
||||||
data = arrayOf(ShareData(url = item.url, title = item.title))
|
data = arrayOf(ShareData(url = item.url, title = item.title))
|
||||||
)
|
)
|
||||||
|
@ -110,7 +111,7 @@ class DefaultHistoryController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleEnterRecentlyClosed() {
|
override fun handleEnterRecentlyClosed() {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
HistoryFragmentDirections.actionGlobalRecentlyClosed(),
|
HistoryFragmentDirections.actionGlobalRecentlyClosed(),
|
||||||
NavOptions.Builder().setPopUpTo(R.id.recentlyClosedFragment, true).build()
|
NavOptions.Builder().setPopUpTo(R.id.recentlyClosedFragment, true).build()
|
||||||
)
|
)
|
||||||
|
|
|
@ -304,10 +304,10 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
|
||||||
val directions = HistoryFragmentDirections.actionGlobalShareFragment(
|
val directions = HistoryFragmentDirections.actionGlobalShareFragment(
|
||||||
data = data.toTypedArray()
|
data = data.toTypedArray()
|
||||||
)
|
)
|
||||||
navigate(directions)
|
navigateToHistoryFragment(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigate(directions: NavDirections) {
|
private fun navigateToHistoryFragment(directions: NavDirections) {
|
||||||
invokePendingDeletion()
|
invokePendingDeletion()
|
||||||
findNavController().nav(
|
findNavController().nav(
|
||||||
R.id.historyFragment,
|
R.id.historyFragment,
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
|
|
||||||
interface RecentlyClosedController {
|
interface RecentlyClosedController {
|
||||||
fun handleOpen(item: RecoverableTab, mode: BrowsingMode? = null)
|
fun handleOpen(item: RecoverableTab, mode: BrowsingMode? = null)
|
||||||
|
@ -48,7 +49,7 @@ class DefaultRecentlyClosedController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleNavigateToHistory() {
|
override fun handleNavigateToHistory() {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
RecentlyClosedFragmentDirections.actionGlobalHistoryFragment(),
|
RecentlyClosedFragmentDirections.actionGlobalHistoryFragment(),
|
||||||
NavOptions.Builder().setPopUpTo(R.id.historyFragment, true).build()
|
NavOptions.Builder().setPopUpTo(R.id.historyFragment, true).build()
|
||||||
)
|
)
|
||||||
|
@ -64,7 +65,7 @@ class DefaultRecentlyClosedController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleShare(item: RecoverableTab) {
|
override fun handleShare(item: RecoverableTab) {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
RecentlyClosedFragmentDirections.actionGlobalShareFragment(
|
RecentlyClosedFragmentDirections.actionGlobalShareFragment(
|
||||||
data = arrayOf(ShareData(url = item.url, title = item.title))
|
data = arrayOf(ShareData(url = item.url, title = item.title))
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.nimbus
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import mozilla.components.service.nimbus.ui.NimbusExperimentsAdapterDelegate
|
import mozilla.components.service.nimbus.ui.NimbusExperimentsAdapterDelegate
|
||||||
import org.mozilla.experiments.nimbus.EnrolledExperiment
|
import org.mozilla.experiments.nimbus.EnrolledExperiment
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View used for managing Nimbus experiments.
|
* View used for managing Nimbus experiments.
|
||||||
|
@ -21,6 +22,6 @@ class NimbusExperimentsView(
|
||||||
experiment.userFacingName
|
experiment.userFacingName
|
||||||
)
|
)
|
||||||
|
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.perf
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import java.util.WeakHashMap
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class asynchronously loads the navigation graph XML. This is a performance optimization:
|
||||||
|
* large nav graphs take ~29ms to inflate on the Moto G5 (#16900). This also seemingly prevents the
|
||||||
|
* HomeFragment layout XML from being unnecessarily inflated when it isn't used, improving perf by
|
||||||
|
* ~148ms on the Moto G5 for VIEW start up (#18245) though it was unintentional and we may wish to
|
||||||
|
* implement more intentional for that.
|
||||||
|
*
|
||||||
|
* This class is defined as an Object, rather than as a class instance in our Components, because
|
||||||
|
* it needs to be called by the [NavController] extension function which can't easily access Components.
|
||||||
|
*
|
||||||
|
* To use this class properly, [inflateNavGraphAsync] must be called first before
|
||||||
|
* [blockForNavGraphInflation] using the same [NavController] instance.
|
||||||
|
*/
|
||||||
|
object NavGraphProvider {
|
||||||
|
|
||||||
|
// We want to store member state on the NavController. However, there is no way to do this.
|
||||||
|
// Instead, we store state as part of a map: NavController instance -> State. In order to
|
||||||
|
// garbage collect our data when the NavController is no longer relevant, we use a WeakHashMap.
|
||||||
|
private val map = WeakHashMap<NavController, Job>()
|
||||||
|
|
||||||
|
fun inflateNavGraphAsync(navController: NavController, lifecycleScope: LifecycleCoroutineScope) {
|
||||||
|
val inflationJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
val inflater = navController.navInflater
|
||||||
|
navController.graph = inflater.inflate(R.navigation.nav_graph)
|
||||||
|
}
|
||||||
|
|
||||||
|
map[navController] = inflationJob
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The job should block the main thread if it isn't completed so that the NavGraph can be loaded
|
||||||
|
* before any navigation is done.
|
||||||
|
*
|
||||||
|
* [inflateNavGraphAsync] must be called before this method.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if [inflateNavGraphAsync] wasn't called first for this [NavController]
|
||||||
|
*/
|
||||||
|
fun blockForNavGraphInflation(navController: NavController) {
|
||||||
|
val inflationJob = map[navController] ?: throw IllegalStateException("Expected " +
|
||||||
|
"`NavGraphProvider.inflateNavGraphAsync` to be called before this method with the same " +
|
||||||
|
"`NavController` instance. If this occurred in a test, you probably need to add the " +
|
||||||
|
"DisableNavGraphProviderAssertionRule.")
|
||||||
|
runBlockingIncrement { inflationJob.join() }
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.application
|
import org.mozilla.fenix.ext.application
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.metrics
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.ext.navigateToNotificationsSettings
|
import org.mozilla.fenix.ext.navigateToNotificationsSettings
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
@ -480,7 +481,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
private fun navigateFromSettings(directions: NavDirections) {
|
private fun navigateFromSettings(directions: NavDirections) {
|
||||||
view?.findNavController()?.let { navController ->
|
view?.findNavController()?.let { navController ->
|
||||||
if (navController.currentDestination?.id == R.id.settingsFragment) {
|
if (navController.currentDestination?.id == R.id.settingsFragment) {
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
|
@ -32,7 +33,7 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
|
||||||
private val exceptionsClickListener = Preference.OnPreferenceClickListener {
|
private val exceptionsClickListener = Preference.OnPreferenceClickListener {
|
||||||
val directions =
|
val directions =
|
||||||
TrackingProtectionFragmentDirections.actionTrackingProtectionFragmentToExceptionsFragment()
|
TrackingProtectionFragmentDirections.actionTrackingProtectionFragmentToExceptionsFragment()
|
||||||
requireView().findNavController().navigate(directions)
|
requireView().findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
private lateinit var customCookies: CheckBoxPreference
|
private lateinit var customCookies: CheckBoxPreference
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.crashes.CrashListActivity
|
import org.mozilla.fenix.crashes.CrashListActivity
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
|
@ -178,7 +179,7 @@ class AboutFragment : Fragment(), AboutPageListener {
|
||||||
|
|
||||||
private fun openLibrariesPage() {
|
private fun openLibrariesPage() {
|
||||||
val navController = findNavController()
|
val navController = findNavController()
|
||||||
navController.navigate(R.id.action_aboutFragment_to_aboutLibrariesFragment)
|
navController.navigateBlockingForAsyncNavGraph(R.id.action_aboutFragment_to_aboutLibrariesFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAboutItemClicked(item: AboutItem) {
|
override fun onAboutItemClicked(item: AboutItem) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
|
@ -59,7 +60,7 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
|
||||||
|
|
||||||
private fun navigateToPairFragment() {
|
private fun navigateToPairFragment() {
|
||||||
val directions = TurnOnSyncFragmentDirections.actionTurnOnSyncFragmentToPairFragment()
|
val directions = TurnOnSyncFragmentDirections.actionTurnOnSyncFragmentToPairFragment()
|
||||||
requireView().findNavController().navigate(directions)
|
requireView().findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
requireComponents.analytics.metrics.track(Event.SyncAuthScanPairing)
|
requireComponents.analytics.metrics.track(Event.SyncAuthScanPairing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.preference.PreferenceFragmentCompat
|
||||||
import mozilla.components.service.fxa.SyncEngine
|
import mozilla.components.service.fxa.SyncEngine
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
import org.mozilla.fenix.settings.SyncPreferenceView
|
import org.mozilla.fenix.settings.SyncPreferenceView
|
||||||
|
@ -39,17 +40,17 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||||
onSignInToSyncClicked = {
|
onSignInToSyncClicked = {
|
||||||
val directions =
|
val directions =
|
||||||
CreditCardsSettingFragmentDirections.actionCreditCardsSettingFragmentToTurnOnSyncFragment()
|
CreditCardsSettingFragmentDirections.actionCreditCardsSettingFragmentToTurnOnSyncFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
},
|
},
|
||||||
onSyncStatusClicked = {
|
onSyncStatusClicked = {
|
||||||
val directions =
|
val directions =
|
||||||
CreditCardsSettingFragmentDirections.actionGlobalAccountSettingsFragment()
|
CreditCardsSettingFragmentDirections.actionGlobalAccountSettingsFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
},
|
},
|
||||||
onReconnectClicked = {
|
onReconnectClicked = {
|
||||||
val directions =
|
val directions =
|
||||||
CreditCardsSettingFragmentDirections.actionGlobalAccountProblemFragment()
|
CreditCardsSettingFragmentDirections.actionGlobalAccountProblemFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -61,13 +62,13 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||||
val directions =
|
val directions =
|
||||||
CreditCardsSettingFragmentDirections
|
CreditCardsSettingFragmentDirections
|
||||||
.actionCreditCardsSettingFragmentToCreditCardEditorFragment()
|
.actionCreditCardsSettingFragmentToCreditCardEditorFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
getPreferenceKey(R.string.pref_key_credit_cards_manage_saved_cards) -> {
|
getPreferenceKey(R.string.pref_key_credit_cards_manage_saved_cards) -> {
|
||||||
val directions =
|
val directions =
|
||||||
CreditCardsSettingFragmentDirections
|
CreditCardsSettingFragmentDirections
|
||||||
.actionCreditCardsSettingFragmentToCreditCardsManagementFragment()
|
.actionCreditCardsSettingFragmentToCreditCardsManagementFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package org.mozilla.fenix.settings.creditcards.controller
|
package org.mozilla.fenix.settings.creditcards.controller
|
||||||
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.settings.creditcards.CreditCardsManagementFragmentDirections
|
import org.mozilla.fenix.settings.creditcards.CreditCardsManagementFragmentDirections
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +28,7 @@ class DefaultCreditCardsManagementController(
|
||||||
) : CreditCardsManagementController {
|
) : CreditCardsManagementController {
|
||||||
|
|
||||||
override fun handleCreditCardClicked() {
|
override fun handleCreditCardClicked() {
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
CreditCardsManagementFragmentDirections
|
CreditCardsManagementFragmentDirections
|
||||||
.actionCreditCardsManagementFragmentToCreditCardEditorFragment()
|
.actionCreditCardsManagementFragmentToCreditCardEditorFragment()
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,6 +28,7 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
|
@ -199,7 +200,7 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da
|
||||||
// If the user deletes all open tabs we need to make sure we remove
|
// If the user deletes all open tabs we need to make sure we remove
|
||||||
// the BrowserFragment from the backstack.
|
// the BrowserFragment from the backstack.
|
||||||
popBackStack(R.id.homeFragment, false)
|
popBackStack(R.id.homeFragment, false)
|
||||||
navigate(DeleteBrowsingDataFragmentDirections.actionGlobalSettingsFragment())
|
navigateBlockingForAsyncNavGraph(DeleteBrowsingDataFragmentDirections.actionGlobalSettingsFragment())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import androidx.navigation.NavController
|
||||||
import org.mozilla.fenix.BrowserDirection
|
import org.mozilla.fenix.BrowserDirection
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
import org.mozilla.fenix.settings.logins.LoginsAction
|
import org.mozilla.fenix.settings.logins.LoginsAction
|
||||||
import org.mozilla.fenix.settings.logins.LoginsFragmentStore
|
import org.mozilla.fenix.settings.logins.LoginsFragmentStore
|
||||||
|
@ -40,7 +41,7 @@ class LoginsListController(
|
||||||
fun handleItemClicked(item: SavedLogin) {
|
fun handleItemClicked(item: SavedLogin) {
|
||||||
loginsFragmentStore.dispatch(LoginsAction.LoginSelected(item))
|
loginsFragmentStore.dispatch(LoginsAction.LoginSelected(item))
|
||||||
metrics.track(Event.OpenOneLogin)
|
metrics.track(Event.OpenOneLogin)
|
||||||
navController.navigate(
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(item.guid)
|
SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(item.guid)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import mozilla.components.service.sync.logins.LoginsStorageException
|
||||||
import mozilla.components.service.sync.logins.NoSuchRecordException
|
import mozilla.components.service.sync.logins.NoSuchRecordException
|
||||||
import mozilla.components.service.sync.logins.SyncableLoginsStorage
|
import mozilla.components.service.sync.logins.SyncableLoginsStorage
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.settings.logins.LoginsAction
|
import org.mozilla.fenix.settings.logins.LoginsAction
|
||||||
import org.mozilla.fenix.settings.logins.LoginsFragmentStore
|
import org.mozilla.fenix.settings.logins.LoginsFragmentStore
|
||||||
import org.mozilla.fenix.settings.logins.fragment.EditLoginFragmentDirections
|
import org.mozilla.fenix.settings.logins.fragment.EditLoginFragmentDirections
|
||||||
|
@ -83,7 +84,7 @@ open class SavedLoginsStorageController(
|
||||||
EditLoginFragmentDirections.actionEditLoginFragmentToLoginDetailFragment(
|
EditLoginFragmentDirections.actionEditLoginFragmentToLoginDetailFragment(
|
||||||
loginId
|
loginId
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
saveLoginJob?.invokeOnCompletion {
|
saveLoginJob?.invokeOnCompletion {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.mozilla.fenix.components.StoreProvider
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.increaseTapArea
|
import org.mozilla.fenix.ext.increaseTapArea
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.redirectToReAuth
|
import org.mozilla.fenix.ext.redirectToReAuth
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
|
@ -199,7 +200,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
|
||||||
LoginDetailFragmentDirections.actionLoginDetailFragmentToEditLoginFragment(
|
LoginDetailFragmentDirections.actionLoginDetailFragmentToEditLoginFragment(
|
||||||
login!!
|
login!!
|
||||||
)
|
)
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun displayDeleteLoginDialog() {
|
private fun displayDeleteLoginDialog() {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
||||||
import org.mozilla.fenix.ext.secure
|
import org.mozilla.fenix.ext.secure
|
||||||
|
@ -130,17 +131,17 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
|
||||||
onSignInToSyncClicked = {
|
onSignInToSyncClicked = {
|
||||||
val directions =
|
val directions =
|
||||||
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment()
|
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
},
|
},
|
||||||
onSyncStatusClicked = {
|
onSyncStatusClicked = {
|
||||||
val directions =
|
val directions =
|
||||||
SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment()
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
},
|
},
|
||||||
onReconnectClicked = {
|
onReconnectClicked = {
|
||||||
val directions =
|
val directions =
|
||||||
SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment()
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -213,19 +214,19 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
|
||||||
context?.components?.analytics?.metrics?.track(Event.OpenLogins)
|
context?.components?.analytics?.metrics?.track(Event.OpenLogins)
|
||||||
val directions =
|
val directions =
|
||||||
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginsListFragment()
|
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginsListFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToSaveLoginSettingFragment() {
|
private fun navigateToSaveLoginSettingFragment() {
|
||||||
val directions =
|
val directions =
|
||||||
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToSavedLoginsSettingFragment()
|
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToSavedLoginsSettingFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToLoginExceptionFragment() {
|
private fun navigateToLoginExceptionFragment() {
|
||||||
val directions =
|
val directions =
|
||||||
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginExceptionsFragment()
|
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginExceptionsFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -18,6 +18,7 @@ import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
|
import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
|
||||||
import mozilla.components.support.base.feature.OnNeedToRequestPermissions
|
import mozilla.components.support.base.feature.OnNeedToRequestPermissions
|
||||||
import org.mozilla.fenix.components.PermissionStorage
|
import org.mozilla.fenix.components.PermissionStorage
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
||||||
import org.mozilla.fenix.settings.toggle
|
import org.mozilla.fenix.settings.toggle
|
||||||
|
@ -199,6 +200,6 @@ class DefaultQuickSettingsController(
|
||||||
private fun navigateToManagePhoneFeature(phoneFeature: PhoneFeature) {
|
private fun navigateToManagePhoneFeature(phoneFeature: PhoneFeature) {
|
||||||
val directions = QuickSettingsSheetDialogFragmentDirections
|
val directions = QuickSettingsSheetDialogFragmentDirections
|
||||||
.actionGlobalSitePermissionsManagePhoneFeature(phoneFeature)
|
.actionGlobalSitePermissionsManagePhoneFeature(phoneFeature)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.getRootView
|
import org.mozilla.fenix.ext.getRootView
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.utils.allowUndo
|
import org.mozilla.fenix.utils.allowUndo
|
||||||
|
|
||||||
class RadioSearchEngineListPreference @JvmOverloads constructor(
|
class RadioSearchEngineListPreference @JvmOverloads constructor(
|
||||||
|
@ -146,7 +147,7 @@ class RadioSearchEngineListPreference @JvmOverloads constructor(
|
||||||
val directions = SearchEngineFragmentDirections
|
val directions = SearchEngineFragmentDirections
|
||||||
.actionSearchEngineFragmentToEditCustomSearchEngineFragment(engine.id)
|
.actionSearchEngineFragmentToEditCustomSearchEngineFragment(engine.id)
|
||||||
|
|
||||||
Navigation.findNavController(view).navigate(directions)
|
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteSearchEngine(
|
private fun deleteSearchEngine(
|
||||||
|
|
|
@ -13,6 +13,7 @@ import androidx.preference.SwitchPreference
|
||||||
import mozilla.components.support.ktx.android.view.hideKeyboard
|
import mozilla.components.support.ktx.android.view.hideKeyboard
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
import org.mozilla.fenix.settings.SharedPreferenceUpdater
|
import org.mozilla.fenix.settings.SharedPreferenceUpdater
|
||||||
|
@ -99,7 +100,7 @@ class SearchEngineFragment : PreferenceFragmentCompat() {
|
||||||
getPreferenceKey(R.string.pref_key_add_search_engine) -> {
|
getPreferenceKey(R.string.pref_key_add_search_engine) -> {
|
||||||
val directions = SearchEngineFragmentDirections
|
val directions = SearchEngineFragmentDirections
|
||||||
.actionSearchEngineFragmentToAddSearchEngineFragment()
|
.actionSearchEngineFragmentToAddSearchEngineFragment()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import kotlinx.coroutines.withContext
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
|
@ -161,6 +162,6 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() {
|
||||||
phoneFeature = phoneFeature,
|
phoneFeature = phoneFeature,
|
||||||
sitePermissions = sitePermissions
|
sitePermissions = sitePermissions
|
||||||
)
|
)
|
||||||
requireView().findNavController().navigate(directions)
|
requireView().findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import androidx.preference.PreferenceFragmentCompat
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
|
@ -42,7 +43,7 @@ class SitePermissionsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
exceptionsCategory.onPreferenceClickListener = OnPreferenceClickListener {
|
exceptionsCategory.onPreferenceClickListener = OnPreferenceClickListener {
|
||||||
val directions = SitePermissionsFragmentDirections.actionSitePermissionsToExceptions()
|
val directions = SitePermissionsFragmentDirections.actionSitePermissionsToExceptions()
|
||||||
Navigation.findNavController(requireView()).navigate(directions)
|
Navigation.findNavController(requireView()).navigateBlockingForAsyncNavGraph(directions)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +77,6 @@ class SitePermissionsFragment : PreferenceFragmentCompat() {
|
||||||
requireComponents.analytics.metrics.track(Event.AutoPlaySettingVisited)
|
requireComponents.analytics.metrics.track(Event.AutoPlaySettingVisited)
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigation.findNavController(requireView()).navigate(directions)
|
Navigation.findNavController(requireView()).navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import mozilla.components.support.ktx.kotlin.isExtensionUrl
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.metrics
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.share.listadapters.AppShareOption
|
import org.mozilla.fenix.share.listadapters.AppShareOption
|
||||||
|
@ -121,7 +122,7 @@ class DefaultShareController(
|
||||||
|
|
||||||
override fun handleAddNewDevice() {
|
override fun handleAddNewDevice() {
|
||||||
val directions = ShareFragmentDirections.actionShareFragmentToAddNewDeviceFragment()
|
val directions = ShareFragmentDirections.actionShareFragmentToAddNewDeviceFragment()
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleShareToDevice(device: Device) {
|
override fun handleShareToDevice(device: Device) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import mozilla.components.concept.sync.DeviceType
|
||||||
import mozilla.components.feature.syncedtabs.view.SyncedTabsView
|
import mozilla.components.feature.syncedtabs.view.SyncedTabsView
|
||||||
import org.mozilla.fenix.NavGraphDirections
|
import org.mozilla.fenix.NavGraphDirections
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.sync.SyncedTabsAdapter.AdapterItem
|
import org.mozilla.fenix.sync.SyncedTabsAdapter.AdapterItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +64,7 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item
|
||||||
errorItem.navController?.let { navController ->
|
errorItem.navController?.let { navController ->
|
||||||
itemView.sync_tabs_error_cta_button.visibility = VISIBLE
|
itemView.sync_tabs_error_cta_button.visibility = VISIBLE
|
||||||
itemView.sync_tabs_error_cta_button.setOnClickListener {
|
itemView.sync_tabs_error_cta_button.setOnClickListener {
|
||||||
navController.navigate(NavGraphDirections.actionGlobalTurnOnSync())
|
navController.navigateBlockingForAsyncNavGraph(NavGraphDirections.actionGlobalTurnOnSync())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
|
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.home.HomeFragment
|
import org.mozilla.fenix.home.HomeFragment
|
||||||
import org.mozilla.fenix.tabstray.ext.getTabSessionState
|
import org.mozilla.fenix.tabstray.ext.getTabSessionState
|
||||||
|
|
||||||
|
@ -91,11 +92,13 @@ class DefaultNavigationInteractor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTabSettingsClicked() {
|
override fun onTabSettingsClicked() {
|
||||||
navController.navigate(TabsTrayFragmentDirections.actionGlobalTabSettingsFragment())
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
|
TabsTrayFragmentDirections.actionGlobalTabSettingsFragment())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOpenRecentlyClosedClicked() {
|
override fun onOpenRecentlyClosedClicked() {
|
||||||
navController.navigate(TabsTrayFragmentDirections.actionGlobalRecentlyClosed())
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
|
TabsTrayFragmentDirections.actionGlobalRecentlyClosed())
|
||||||
metrics.track(Event.RecentlyClosedTabsOpened)
|
metrics.track(Event.RecentlyClosedTabsOpened)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +109,7 @@ class DefaultNavigationInteractor(
|
||||||
val directions = TabsTrayFragmentDirections.actionGlobalShareFragment(
|
val directions = TabsTrayFragmentDirections.actionGlobalShareFragment(
|
||||||
data = data.toTypedArray()
|
data = data.toTypedArray()
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShareTabsOfTypeClicked(private: Boolean) {
|
override fun onShareTabsOfTypeClicked(private: Boolean) {
|
||||||
|
@ -117,7 +120,7 @@ class DefaultNavigationInteractor(
|
||||||
val directions = TabsTrayFragmentDirections.actionGlobalShareFragment(
|
val directions = TabsTrayFragmentDirections.actionGlobalShareFragment(
|
||||||
data = data.toTypedArray()
|
data = data.toTypedArray()
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.tabtray.TabTrayDialogFragmentDirections
|
import org.mozilla.fenix.tabtray.TabTrayDialogFragmentDirections
|
||||||
|
|
||||||
interface TabsTrayController {
|
interface TabsTrayController {
|
||||||
|
@ -43,7 +44,8 @@ class DefaultTabsTrayController(
|
||||||
override fun onNewTabTapped(isPrivate: Boolean) {
|
override fun onNewTabTapped(isPrivate: Boolean) {
|
||||||
val startTime = profiler?.getProfilerTime()
|
val startTime = profiler?.getProfilerTime()
|
||||||
browsingModeManager.mode = BrowsingMode.fromBoolean(isPrivate)
|
browsingModeManager.mode = BrowsingMode.fromBoolean(isPrivate)
|
||||||
navController.navigate(TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
|
TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
|
||||||
navigationInteractor.onTabTrayDismissed()
|
navigationInteractor.onTabTrayDismissed()
|
||||||
profiler?.addMarker(
|
profiler?.addMarker(
|
||||||
"DefaultTabTrayController.onNewTabTapped",
|
"DefaultTabTrayController.onNewTabTapped",
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.mozilla.fenix.NavGraphDirections
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.StoreProvider
|
import org.mozilla.fenix.components.StoreProvider
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.home.HomeScreenViewModel
|
import org.mozilla.fenix.home.HomeScreenViewModel
|
||||||
import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor
|
import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor
|
||||||
|
@ -241,7 +242,7 @@ class TabsTrayFragment : AppCompatDialogFragment(), TabsTrayInteractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!navController.popBackStack(R.id.browserFragment, false)) {
|
if (!navController.popBackStack(R.id.browserFragment, false)) {
|
||||||
navController.navigate(R.id.browserFragment)
|
navController.navigateBlockingForAsyncNavGraph(R.id.browserFragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +302,7 @@ class TabsTrayFragment : AppCompatDialogFragment(), TabsTrayInteractor {
|
||||||
private fun dismissTabTrayAndNavigateHome(sessionId: String) {
|
private fun dismissTabTrayAndNavigateHome(sessionId: String) {
|
||||||
homeViewModel.sessionToDelete = sessionId
|
homeViewModel.sessionToDelete = sessionId
|
||||||
val directions = NavGraphDirections.actionGlobalHome()
|
val directions = NavGraphDirections.actionGlobalHome()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
||||||
import org.mozilla.fenix.components.TabCollectionStorage
|
import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.home.HomeFragment
|
import org.mozilla.fenix.home.HomeFragment
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +105,8 @@ class DefaultTabTrayController(
|
||||||
override fun handleNewTabTapped(private: Boolean) {
|
override fun handleNewTabTapped(private: Boolean) {
|
||||||
val startTime = profiler?.getProfilerTime()
|
val startTime = profiler?.getProfilerTime()
|
||||||
browsingModeManager.mode = BrowsingMode.fromBoolean(private)
|
browsingModeManager.mode = BrowsingMode.fromBoolean(private)
|
||||||
navController.navigate(TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
|
TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
|
||||||
dismissTabTray()
|
dismissTabTray()
|
||||||
profiler?.addMarker(
|
profiler?.addMarker(
|
||||||
"DefaultTabTrayController.onNewTabTapped",
|
"DefaultTabTrayController.onNewTabTapped",
|
||||||
|
@ -113,7 +115,8 @@ class DefaultTabTrayController(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleTabSettingsClicked() {
|
override fun handleTabSettingsClicked() {
|
||||||
navController.navigate(TabTrayDialogFragmentDirections.actionGlobalTabSettingsFragment())
|
navController.navigateBlockingForAsyncNavGraph(
|
||||||
|
TabTrayDialogFragmentDirections.actionGlobalTabSettingsFragment())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleTabTrayDismissed() {
|
override fun handleTabTrayDismissed() {
|
||||||
|
@ -148,7 +151,7 @@ class DefaultTabTrayController(
|
||||||
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
|
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
|
||||||
data = data.toTypedArray()
|
data = data.toTypedArray()
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleShareSelectedTabsClicked(selectedTabs: Set<Tab>) {
|
override fun handleShareSelectedTabsClicked(selectedTabs: Set<Tab>) {
|
||||||
|
@ -158,7 +161,7 @@ class DefaultTabTrayController(
|
||||||
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
|
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
|
||||||
data = data.toTypedArray()
|
data = data.toTypedArray()
|
||||||
)
|
)
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleBookmarkSelectedTabs(selectedTabs: Set<Tab>) {
|
override fun handleBookmarkSelectedTabs(selectedTabs: Set<Tab>) {
|
||||||
|
@ -236,13 +239,13 @@ class DefaultTabTrayController(
|
||||||
|
|
||||||
override fun handleRecentlyClosedClicked() {
|
override fun handleRecentlyClosedClicked() {
|
||||||
val directions = TabTrayDialogFragmentDirections.actionGlobalRecentlyClosed()
|
val directions = TabTrayDialogFragmentDirections.actionGlobalRecentlyClosed()
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
metrics.track(Event.RecentlyClosedTabsOpened)
|
metrics.track(Event.RecentlyClosedTabsOpened)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleGoToTabsSettingClicked() {
|
override fun handleGoToTabsSettingClicked() {
|
||||||
val directions = TabTrayDialogFragmentDirections.actionGlobalTabSettingsFragment()
|
val directions = TabTrayDialogFragmentDirections.actionGlobalTabSettingsFragment()
|
||||||
navController.navigate(directions)
|
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||||
metrics.track(Event.TabsTrayCfrTapped)
|
metrics.track(Event.TabsTrayCfrTapped)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.getDefaultCollectionNumber
|
import org.mozilla.fenix.ext.getDefaultCollectionNumber
|
||||||
|
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||||
import org.mozilla.fenix.ext.metrics
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
|
@ -331,7 +332,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
|
||||||
private fun dismissTabTrayAndNavigateHome(sessionId: String) {
|
private fun dismissTabTrayAndNavigateHome(sessionId: String) {
|
||||||
homeViewModel.sessionToDelete = sessionId
|
homeViewModel.sessionToDelete = sessionId
|
||||||
val directions = NavGraphDirections.actionGlobalHome()
|
val directions = NavGraphDirections.actionGlobalHome()
|
||||||
findNavController().navigate(directions)
|
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +345,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
if (findNavController().currentDestination?.id == R.id.browserFragment) return
|
if (findNavController().currentDestination?.id == R.id.browserFragment) return
|
||||||
if (!findNavController().popBackStack(R.id.browserFragment, false)) {
|
if (!findNavController().popBackStack(R.id.browserFragment, false)) {
|
||||||
findNavController().navigate(R.id.browserFragment)
|
findNavController().navigateBlockingForAsyncNavGraph(R.id.browserFragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +380,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
|
||||||
.setText(requireContext().getString(messageStringRes))
|
.setText(requireContext().getString(messageStringRes))
|
||||||
.setAction(requireContext().getString(R.string.create_collection_view)) {
|
.setAction(requireContext().getString(R.string.create_collection_view)) {
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
findNavController().navigate(
|
findNavController().navigateBlockingForAsyncNavGraph(
|
||||||
TabTrayDialogFragmentDirections.actionGlobalHome(
|
TabTrayDialogFragmentDirections.actionGlobalHome(
|
||||||
focusOnAddressBar = false,
|
focusOnAddressBar = false,
|
||||||
focusOnCollection = collectionToSelect ?: -1L
|
focusOnCollection = collectionToSelect ?: -1L
|
||||||
|
@ -403,7 +404,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
|
||||||
.setText(requireContext().getString(R.string.snackbar_message_bookmarks_saved))
|
.setText(requireContext().getString(R.string.snackbar_message_bookmarks_saved))
|
||||||
.setAction(requireContext().getString(R.string.snackbar_message_bookmarks_view)) {
|
.setAction(requireContext().getString(R.string.snackbar_message_bookmarks_view)) {
|
||||||
dismissAllowingStateLoss()
|
dismissAllowingStateLoss()
|
||||||
findNavController().navigate(
|
findNavController().navigateBlockingForAsyncNavGraph(
|
||||||
TabTrayDialogFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id)
|
TabTrayDialogFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="56dp" />
|
android:layout_height="56dp" />
|
||||||
|
|
||||||
|
<!--The navGraph is set dynamically in NavGraphProvider -->
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/container"
|
android:id="@+id/container"
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:defaultNavHost="true"
|
app:defaultNavHost="true"/>
|
||||||
app:navGraph="@navigation/nav_graph" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -12,14 +12,20 @@ import io.mockk.verify
|
||||||
import mozilla.components.lib.crash.Crash
|
import mozilla.components.lib.crash.Crash
|
||||||
import mozilla.components.support.test.ext.joinBlocking
|
import mozilla.components.support.test.ext.joinBlocking
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.Components
|
import org.mozilla.fenix.components.Components
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
class CrashReporterControllerTest {
|
class CrashReporterControllerTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
private lateinit var components: Components
|
private lateinit var components: Components
|
||||||
private lateinit var crash: Crash
|
private lateinit var crash: Crash
|
||||||
private lateinit var sessionId: String
|
private lateinit var sessionId: String
|
||||||
|
|
|
@ -18,11 +18,16 @@ import io.mockk.mockkStatic
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import io.sentry.Sentry
|
import io.sentry.Sentry
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.components.isSentryEnabled
|
import org.mozilla.fenix.components.isSentryEnabled
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
|
|
||||||
class NavControllerTest {
|
class NavControllerTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
private val currentDestId = 4
|
private val currentDestId = 4
|
||||||
@MockK(relaxUnitFun = true) private lateinit var navController: NavController
|
@MockK(relaxUnitFun = true) private lateinit var navController: NavController
|
||||||
@MockK private lateinit var navDirections: NavDirections
|
@MockK private lateinit var navDirections: NavDirections
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.helpers
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockkObject
|
||||||
|
import io.mockk.unmockkObject
|
||||||
|
import org.junit.rules.TestWatcher
|
||||||
|
import org.junit.runner.Description
|
||||||
|
import org.mozilla.fenix.perf.NavGraphProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the call order assertions defined by the [NavGraphProvider] for use in testing.
|
||||||
|
* This is necessary because unit tests generally don't follow the application lifecycle and thus
|
||||||
|
* call the methods out of order, causing an assertion to be thrown unexpectedly. You may need to
|
||||||
|
* apply this rule if you see the following exception in your test:
|
||||||
|
*
|
||||||
|
* Unfortunately, JUnit 4 discourages setting test state globally so we apply this to each test that
|
||||||
|
* has the failure rather than disabling it globally.
|
||||||
|
*/
|
||||||
|
class DisableNavGraphProviderAssertionRule : TestWatcher() {
|
||||||
|
|
||||||
|
// public for code reuse.
|
||||||
|
fun setUp() {
|
||||||
|
mockkObject(NavGraphProvider)
|
||||||
|
every { NavGraphProvider.blockForNavGraphInflation(any()) } returns Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
// public for code reuse.
|
||||||
|
fun tearDown() { //
|
||||||
|
unmockkObject(NavGraphProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun starting(description: Description?) {
|
||||||
|
setUp()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun finished(description: Description?) {
|
||||||
|
tearDown()
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,13 +7,19 @@ package org.mozilla.fenix.helpers
|
||||||
import org.mozilla.fenix.FenixApplication
|
import org.mozilla.fenix.FenixApplication
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.TestComponents
|
import org.mozilla.fenix.components.TestComponents
|
||||||
|
import org.robolectric.TestLifecycleApplication
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An override of our application for use in Robolectric-based unit tests. We're forced to override
|
* An override of our application for use in Robolectric-based unit tests. We're forced to override
|
||||||
* because our standard application fails to initialize in Robolectric with exceptions like:
|
* because our standard application fails to initialize in Robolectric with exceptions like:
|
||||||
* "Crash handler service must run in a separate process".
|
* "Crash handler service must run in a separate process".
|
||||||
*/
|
*/
|
||||||
class FenixRobolectricTestApplication : FenixApplication() {
|
class FenixRobolectricTestApplication : FenixApplication(), TestLifecycleApplication {
|
||||||
|
|
||||||
|
// Though JUnit 4 discourages global rules, we can apply global rules in robolectric so we do
|
||||||
|
// to prevent confusion from devs.
|
||||||
|
private val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
@ -37,4 +43,19 @@ class FenixRobolectricTestApplication : FenixApplication() {
|
||||||
// https://github.com/mozilla-mobile/fenix/pull/15646#issuecomment-709411141
|
// https://github.com/mozilla-mobile/fenix/pull/15646#issuecomment-709411141
|
||||||
setTheme(R.style.NormalTheme)
|
setTheme(R.style.NormalTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before test runs before the test class is initialized
|
||||||
|
override fun beforeTest(method: Method?) {}
|
||||||
|
|
||||||
|
// Prepare test runs once the test class and all its member variables (mock and
|
||||||
|
// non mocks) are initialized. This method runs after application.onCreate
|
||||||
|
override fun prepareTest(test: Any?) {
|
||||||
|
// We call this in prepareTest rather than beforeTest because member vars
|
||||||
|
// are initialized so it feels more correct to call it here.
|
||||||
|
disableNavGraphProviderAssertionRule.setUp()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterTest(method: Method?) {
|
||||||
|
disableNavGraphProviderAssertionRule.tearDown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.BrowserDirection
|
import org.mozilla.fenix.BrowserDirection
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.Analytics
|
import org.mozilla.fenix.components.Analytics
|
||||||
import org.mozilla.fenix.components.TabCollectionStorage
|
import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
|
@ -113,6 +114,9 @@ class DefaultSessionControlControllerTest {
|
||||||
private lateinit var store: BrowserStore
|
private lateinit var store: BrowserStore
|
||||||
private lateinit var controller: DefaultSessionControlController
|
private lateinit var controller: DefaultSessionControlController
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
store = BrowserStore(
|
store = BrowserStore(
|
||||||
|
|
|
@ -30,9 +30,11 @@ import mozilla.components.concept.storage.BookmarkNodeType
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.BrowserDirection
|
import org.mozilla.fenix.BrowserDirection
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
import org.mozilla.fenix.components.Services
|
import org.mozilla.fenix.components.Services
|
||||||
|
@ -87,6 +89,9 @@ class BookmarkControllerTest {
|
||||||
BookmarkNodeType.FOLDER, BookmarkRoot.Root.id, null, 0, BookmarkRoot.Root.name, null, null
|
BookmarkNodeType.FOLDER, BookmarkRoot.Root.id, null, 0, BookmarkRoot.Root.name, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
every { homeActivity.components.services } returns services
|
every { homeActivity.components.services } returns services
|
||||||
|
|
|
@ -26,13 +26,16 @@ import mozilla.components.browser.state.store.BrowserStore
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.BrowserDirection
|
import org.mozilla.fenix.BrowserDirection
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
import org.mozilla.fenix.components.metrics.MetricsUtils
|
import org.mozilla.fenix.components.metrics.MetricsUtils
|
||||||
|
|
||||||
import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGlobalAddonsManagementFragment
|
import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGlobalAddonsManagementFragment
|
||||||
import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGlobalSearchEngineFragment
|
import org.mozilla.fenix.search.SearchDialogFragmentDirections.Companion.actionGlobalSearchEngineFragment
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
|
@ -55,13 +58,14 @@ class SearchDialogControllerTest {
|
||||||
|
|
||||||
private lateinit var controller: SearchDialogController
|
private lateinit var controller: SearchDialogController
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
mockkObject(MetricsUtils)
|
mockkObject(MetricsUtils)
|
||||||
|
|
||||||
val browserStore = BrowserStore()
|
val browserStore = BrowserStore()
|
||||||
|
|
||||||
every { store.state.tabId } returns "test-tab-id"
|
every { store.state.tabId } returns "test-tab-id"
|
||||||
every { store.state.searchEngineSource.searchEngine } returns searchEngine
|
every { store.state.searchEngineSource.searchEngine } returns searchEngine
|
||||||
every { sessionManager.select(any()) } just Runs
|
every { sessionManager.select(any()) } just Runs
|
||||||
|
|
|
@ -13,11 +13,16 @@ import io.mockk.verify
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
|
||||||
class AccountSettingsInteractorTest {
|
class AccountSettingsInteractorTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onSyncNow() {
|
fun onSyncNow() {
|
||||||
var ranSyncNow = false
|
var ranSyncNow = false
|
||||||
|
|
|
@ -9,8 +9,10 @@ import io.mockk.mockk
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardsManagementController
|
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardsManagementController
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
|
|
||||||
class DefaultCreditCardsManagementControllerTest {
|
class DefaultCreditCardsManagementControllerTest {
|
||||||
|
|
||||||
|
@ -18,6 +20,9 @@ class DefaultCreditCardsManagementControllerTest {
|
||||||
|
|
||||||
private lateinit var controller: DefaultCreditCardsManagementController
|
private lateinit var controller: DefaultCreditCardsManagementController
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
controller = spyk(
|
controller = spyk(
|
||||||
|
|
|
@ -20,10 +20,12 @@ import mozilla.components.browser.state.store.BrowserStore
|
||||||
import mozilla.components.concept.tabstray.Tab
|
import mozilla.components.concept.tabstray.Tab
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.collections.CollectionsDialog
|
import org.mozilla.fenix.collections.CollectionsDialog
|
||||||
import org.mozilla.fenix.collections.show
|
import org.mozilla.fenix.collections.show
|
||||||
import org.mozilla.fenix.components.TabCollectionStorage
|
import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
|
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.components.metrics.MetricController
|
import org.mozilla.fenix.components.metrics.MetricController
|
||||||
|
@ -42,6 +44,9 @@ class NavigationInteractorTest {
|
||||||
private val context: Context = mockk(relaxed = true)
|
private val context: Context = mockk(relaxed = true)
|
||||||
private val collectionStorage: TabCollectionStorage = mockk(relaxed = true)
|
private val collectionStorage: TabCollectionStorage = mockk(relaxed = true)
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
store = BrowserStore(initialState = BrowserState(tabs = listOf(testTab)))
|
store = BrowserStore(initialState = BrowserState(tabs = listOf(testTab)))
|
||||||
|
|
|
@ -31,8 +31,10 @@ import mozilla.components.feature.tabs.TabsUseCases
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
||||||
|
@ -68,6 +70,9 @@ class DefaultTabTrayControllerTest {
|
||||||
private val tab1 = createTab(url = "http://firefox.com", id = "5678")
|
private val tab1 = createTab(url = "http://firefox.com", id = "5678")
|
||||||
private val tab2 = createTab(url = "http://mozilla.org", id = "1234")
|
private val tab2 = createTab(url = "http://mozilla.org", id = "1234")
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
mockkStatic("org.mozilla.fenix.ext.SessionManagerKt")
|
mockkStatic("org.mozilla.fenix.ext.SessionManagerKt")
|
||||||
|
|
|
@ -122,6 +122,9 @@ mozilla-detekt-rules:
|
||||||
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
|
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
|
||||||
MozillaUseLazyMonitored:
|
MozillaUseLazyMonitored:
|
||||||
active: true
|
active: true
|
||||||
|
MozillaNavigateCheck:
|
||||||
|
active: true
|
||||||
|
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
|
||||||
|
|
||||||
empty-blocks:
|
empty-blocks:
|
||||||
active: true
|
active: true
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.gitlab.arturbosch.detekt.api.Config
|
||||||
import io.gitlab.arturbosch.detekt.api.RuleSet
|
import io.gitlab.arturbosch.detekt.api.RuleSet
|
||||||
import io.gitlab.arturbosch.detekt.api.RuleSetProvider
|
import io.gitlab.arturbosch.detekt.api.RuleSetProvider
|
||||||
import org.mozilla.fenix.detektrules.perf.MozillaBannedPropertyAccess
|
import org.mozilla.fenix.detektrules.perf.MozillaBannedPropertyAccess
|
||||||
|
import org.mozilla.fenix.detektrules.perf.MozillaNavigateCheck
|
||||||
import org.mozilla.fenix.detektrules.perf.MozillaStrictModeSuppression
|
import org.mozilla.fenix.detektrules.perf.MozillaStrictModeSuppression
|
||||||
import org.mozilla.fenix.detektrules.perf.MozillaRunBlockingCheck
|
import org.mozilla.fenix.detektrules.perf.MozillaRunBlockingCheck
|
||||||
import org.mozilla.fenix.detektrules.perf.MozillaUseLazyMonitored
|
import org.mozilla.fenix.detektrules.perf.MozillaUseLazyMonitored
|
||||||
|
@ -22,7 +23,8 @@ class CustomRulesetProvider : RuleSetProvider {
|
||||||
MozillaStrictModeSuppression(config),
|
MozillaStrictModeSuppression(config),
|
||||||
MozillaCorrectUnitTestRunner(config),
|
MozillaCorrectUnitTestRunner(config),
|
||||||
MozillaRunBlockingCheck(config),
|
MozillaRunBlockingCheck(config),
|
||||||
MozillaUseLazyMonitored(config)
|
MozillaUseLazyMonitored(config),
|
||||||
|
MozillaNavigateCheck(config)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.detektrules.perf
|
||||||
|
|
||||||
|
import io.gitlab.arturbosch.detekt.api.CodeSmell
|
||||||
|
import io.gitlab.arturbosch.detekt.api.Config
|
||||||
|
import io.gitlab.arturbosch.detekt.api.Debt
|
||||||
|
import io.gitlab.arturbosch.detekt.api.Entity
|
||||||
|
import io.gitlab.arturbosch.detekt.api.Issue
|
||||||
|
import io.gitlab.arturbosch.detekt.api.Rule
|
||||||
|
import io.gitlab.arturbosch.detekt.api.Severity
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
|
|
||||||
|
private const val VIOLATION_MSG = "If you named a method `navigate`, please rename it to something a bit" +
|
||||||
|
"more specific such as `navigateTo...`. However, if you are trying to invoke the Android NavController.navigate" +
|
||||||
|
"please use `org.mozilla.fenix.ext.NavController.navigateBlockingForAsyncNavGraph`" +
|
||||||
|
"instead. Because using `navigate` directly in the code can lead to the NavGraph not being loaded" +
|
||||||
|
"since it relies on a blocking call done in `navigateBlockingForAsyncNavGraph`."
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A check to prevent the use of `navController.navigate`. Since the NavGraph is loaded dynamically
|
||||||
|
* and asynchronously, there is a check in place to make sure the graph is loaded by wrapping the
|
||||||
|
* `navigate` function. However, using it directly might lead to code that needs the NavGraph being
|
||||||
|
* called before it being inflated.
|
||||||
|
*/
|
||||||
|
class MozillaNavigateCheck(config: Config = Config.empty) : Rule(config) {
|
||||||
|
|
||||||
|
override val issue = Issue(
|
||||||
|
"MozillaNavigateCheck",
|
||||||
|
Severity.Performance,
|
||||||
|
"Prevents us from calling `navController.navigate` instead of the functions that" +
|
||||||
|
"wrap it",
|
||||||
|
Debt.TEN_MINS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
override fun visitCallExpression(expression: KtCallExpression) {
|
||||||
|
super.visitCallExpression(expression)
|
||||||
|
|
||||||
|
val calledMethod = expression.calleeExpression?.firstChild?.node?.chars
|
||||||
|
|
||||||
|
//We check for the navigate method and we have to ignore our extension function file, since
|
||||||
|
//we call navigate there
|
||||||
|
if (calledMethod == "navigate" ) {
|
||||||
|
report(CodeSmell(issue, Entity.from(expression), VIOLATION_MSG))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue