Closes #19921: Update appcompat and fragment dependencies to 1.3.x

upstream-sync
Roger Yang 3 years ago committed by mergify[bot]
parent 7dbfca2d2e
commit 74c1cc82fb

@ -15,7 +15,6 @@ import mozilla.components.concept.engine.request.RequestInterceptor
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.isOnline
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import java.lang.ref.WeakReference
class AppRequestInterceptor(
@ -98,7 +97,7 @@ class AppRequestInterceptor(
// Navigate and trigger add-on installation.
matchResult.groupValues.getOrNull(1)?.let { addonId ->
navController?.get()?.navigateBlockingForAsyncNavGraph(
navController?.get()?.navigate(
NavGraphDirections.actionGlobalAddonsManagementFragment(addonId)
)

@ -79,7 +79,6 @@ import org.mozilla.fenix.exceptions.trackingprotection.TrackingProtectionExcepti
import org.mozilla.fenix.ext.alreadyOnDestination
import org.mozilla.fenix.ext.breadcrumb
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.measureNoInline
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
@ -95,7 +94,6 @@ import org.mozilla.fenix.library.bookmarks.BookmarkFragmentDirections
import org.mozilla.fenix.library.bookmarks.DesktopFolders
import org.mozilla.fenix.library.history.HistoryFragmentDirections
import org.mozilla.fenix.library.recentlyclosed.RecentlyClosedFragmentDirections
import org.mozilla.fenix.perf.NavGraphProvider
import org.mozilla.fenix.perf.Performance
import org.mozilla.fenix.perf.PerformanceInflater
import org.mozilla.fenix.perf.ProfilerMarkers
@ -199,11 +197,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
components.publicSuffixList.prefetch()
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)
}
setContentView(R.layout.activity_home)
// Must be after we set the content view
if (isVisuallyComplete) {
@ -588,6 +582,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
super.onBackPressed()
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19919
final override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach {
if (it is ActivityResultHandler && it.onActivityResult(requestCode, data, resultCode)) {
@ -952,7 +948,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
webExtensionId = webExtensionState.id,
webExtensionTitle = webExtensionState.name
)
navHost.navController.navigateBlockingForAsyncNavGraph(action)
navHost.navController.navigate(action)
}
/**

@ -33,6 +33,8 @@ abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, User
protected var engineSession: EngineSession? = null
private var canGoBack: Boolean = false
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
session?.let {
promptsFeature.set(

@ -8,7 +8,6 @@ import androidx.navigation.NavController
import mozilla.components.feature.addons.Addon
import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.navigateSafe
/**
@ -56,6 +55,6 @@ class AddonsManagementView(
AddonsManagementFragmentDirections.actionAddonsManagementFragmentToNotYetSupportedAddonFragment(
unsupportedAddons.toTypedArray()
)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
}

@ -25,7 +25,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.ext.runIfFragmentIsAttached
@ -212,7 +211,7 @@ class InstalledAddonDetailsFragment : Fragment() {
InstalledAddonDetailsFragmentDirections
.actionInstalledAddonFragmentToAddonInternalSettingsFragment(addon)
}
Navigation.findNavController(this).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(this).navigate(directions)
}
}
}
@ -223,7 +222,7 @@ class InstalledAddonDetailsFragment : Fragment() {
InstalledAddonDetailsFragmentDirections.actionInstalledAddonFragmentToAddonDetailsFragment(
addon
)
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(view).navigate(directions)
}
}
@ -233,7 +232,7 @@ class InstalledAddonDetailsFragment : Fragment() {
InstalledAddonDetailsFragmentDirections.actionInstalledAddonFragmentToAddonPermissionsDetailsFragment(
addon
)
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(view).navigate(directions)
}
}

@ -131,7 +131,6 @@ import java.lang.ref.WeakReference
import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior
import mozilla.components.feature.webauthn.WebAuthnFeature
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.kotlin.getOrigin
import org.mozilla.fenix.GleanMetrics.PerfStartup
@ -266,7 +265,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
}
}
@Suppress("ComplexMethod", "LongMethod")
@Suppress("ComplexMethod", "LongMethod", "DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
@CallSuper
internal open fun initializeUI(view: View, tab: SessionState) {
val context = requireContext()
@ -585,7 +585,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
showPage = true,
sessionId = getCurrentTab()?.id
)
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
},
onNeedToRequestPermissions = { permissions ->
@ -596,14 +596,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
browserAnimator.captureEngineViewAndDrawStatically {
val directions =
NavGraphDirections.actionGlobalSavedLoginsAuthFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
},
creditCardPickerView = creditCardSelectBar,
onManageCreditCards = {
val directions =
NavGraphDirections.actionGlobalCreditCardsSettingFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
},
onSelectCreditCard = {
showBiometricPrompt(context)
@ -1076,7 +1076,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
}
override fun onBackLongPressed(): Boolean {
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
NavGraphDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSessionId
)

@ -36,7 +36,6 @@ import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.navigateSafe
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
@ -305,7 +304,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
)
.setText(view.context.getString(messageStringRes))
.setAction(requireContext().getString(R.string.create_collection_view)) {
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = false)
)
}

@ -274,6 +274,8 @@ class ToolbarGestureHandler(
}.start()
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19929
private fun PointF.isInToolbar(): Boolean {
val toolbarLocation = toolbarLayout.getRectWithScreenLocation()
// In Android 10, the system gesture touch area overlaps the bottom of the toolbar, so

@ -25,7 +25,6 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.toolbar.interactor.BrowserToolbarInteractor
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeScreenViewModel
@ -125,7 +124,7 @@ class DefaultBrowserToolbarController(
// When closing the last tab we must show the undo snackbar in the home fragment
if (store.state.getNormalOrPrivateTabs(it.content.private).count() == 1) {
homeViewModel.sessionToDelete = it.id
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalHome()
)
} else {
@ -139,7 +138,7 @@ class DefaultBrowserToolbarController(
Event.TabCounterMenuItemTapped(Event.TabCounterMenuItemTapped.Item.NEW_TAB)
)
activity.browsingModeManager.mode = BrowsingMode.Normal
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
)
}
@ -150,7 +149,7 @@ class DefaultBrowserToolbarController(
)
)
activity.browsingModeManager.mode = BrowsingMode.Private
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
)
}
@ -166,7 +165,7 @@ class DefaultBrowserToolbarController(
override fun handleHomeButtonClick() {
metrics.track(Event.BrowserToolbarHomeButtonClicked)
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalHome()
)
}

@ -40,7 +40,6 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.navigateSafe
import org.mozilla.fenix.ext.openSetDefaultBrowserOption
@ -164,7 +163,7 @@ class DefaultBrowserToolbarMenuController(
}
is ToolbarMenu.Item.Back -> {
if (item.viewHistory) {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSessionId
)
@ -177,7 +176,7 @@ class DefaultBrowserToolbarMenuController(
}
is ToolbarMenu.Item.Forward -> {
if (item.viewHistory) {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSessionId
)
@ -214,7 +213,7 @@ class DefaultBrowserToolbarMenuController(
),
showPage = true
)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
is ToolbarMenu.Item.Settings -> browserAnimator.captureEngineViewAndDrawStatically {
val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment()
@ -347,7 +346,7 @@ class DefaultBrowserToolbarMenuController(
)
}
is ToolbarMenu.Item.NewTab -> {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
)
}

@ -11,12 +11,10 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.asLiveData
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.observe
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.plus
import mozilla.components.feature.logins.exceptions.LoginException
import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider
@ -62,7 +60,7 @@ class LoginExceptionsFragment : Fragment() {
private fun subscribeToLoginExceptions() {
requireComponents.core.loginExceptionStorage.getLoginExceptions().asLiveData()
.observe<List<LoginException>>(viewLifecycleOwner) { exceptions ->
.observe(viewLifecycleOwner) { exceptions ->
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(exceptions))
}
}

@ -2,9 +2,6 @@
* 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/. */
// 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
import androidx.annotation.IdRes
@ -13,15 +10,12 @@ import androidx.navigation.NavDirections
import androidx.navigation.NavOptions
import io.sentry.Sentry
import org.mozilla.fenix.components.isSentryEnabled
import org.mozilla.fenix.perf.NavGraphProvider
/**
* Navigate from the fragment with [id] using the given [directions].
* If the id doesn't match the current destination, an error is recorded.
*/
fun NavController.nav(@IdRes id: Int?, directions: NavDirections, navOptions: NavOptions? = null) {
NavGraphProvider.blockForNavGraphInflation(this)
if (id == null || this.currentDestination?.id == id) {
this.navigate(directions, navOptions)
} else {
@ -29,21 +23,6 @@ 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 {
return destId?.let { currentDestination?.id == it || popBackStack(it, false) } ?: false
}
@ -59,6 +38,6 @@ fun NavController.navigateSafe(
directions: NavDirections
) {
if (currentDestination?.id == resId) {
this.navigateBlockingForAsyncNavGraph(directions)
this.navigate(directions)
}
}

@ -158,6 +158,8 @@ internal fun View.getWindowVisibleDisplayFrame(): Rect = with(Rect()) {
}
@VisibleForTesting
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19929
internal fun View.getKeyboardHeight(): Int {
val windowRect = getWindowVisibleDisplayFrame()
val statusBarHeight = windowRect.top

@ -106,7 +106,6 @@ import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.ext.asRecentTabs
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.hideToolbar
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.measureNoInline
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
@ -558,7 +557,7 @@ class HomeFragment : Fragment() {
requireContext().getString(R.string.snackbar_deleted_undo),
{
requireComponents.useCases.tabsUseCases.undo.invoke()
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
HomeFragmentDirections.actionGlobalBrowser(null)
)
},
@ -650,7 +649,7 @@ class HomeFragment : Fragment() {
}
private fun navToSavedLogins() {
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
HomeFragmentDirections.actionGlobalSavedLoginsAuthFragment())
}

@ -8,7 +8,6 @@ import android.content.Intent
import androidx.navigation.NavController
import mozilla.components.lib.crash.Crash
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
/**
* When the app crashes, the user has the option to report it.
@ -27,6 +26,6 @@ class CrashReporterIntentProcessor : HomeIntentProcessor {
private fun openToCrashReporter(intent: Intent, navController: NavController) {
val directions = NavGraphDirections.actionGlobalCrashReporter(intent)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
}

@ -8,7 +8,6 @@ import androidx.navigation.NavController
import mozilla.components.feature.tabs.TabsUseCases.SelectTabUseCase
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.home.HomeFragmentDirections
import org.mozilla.fenix.home.recenttabs.interactor.RecentTabInteractor
@ -41,7 +40,7 @@ class DefaultRecentTabsController(
override fun handleRecentTabClicked(tabId: String) {
selectTabUseCase.invoke(tabId)
navController.navigateBlockingForAsyncNavGraph(R.id.browserFragment)
navController.navigate(R.id.browserFragment)
}
override fun handleRecentTabShowAllClicked() {

@ -11,7 +11,6 @@ import kotlinx.android.synthetic.main.onboarding_manual_signin.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.home.HomeFragmentDirections
class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(view) {
@ -23,7 +22,7 @@ class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(vie
it.context.components.analytics.metrics.track(Event.OnboardingManualSignIn)
val directions = HomeFragmentDirections.actionGlobalTurnOnSync()
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(view).navigate(directions)
}
}

@ -15,7 +15,6 @@ import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.library.LibraryPageView
import org.mozilla.fenix.selection.SelectionInteractor
@ -120,7 +119,7 @@ class BookmarkView(
adapter = bookmarkAdapter
}
view.bookmark_folders_sign_in.setOnClickListener {
navController.navigateBlockingForAsyncNavGraph(NavGraphDirections.actionGlobalTurnOnSync())
navController.navigate(NavGraphDirections.actionGlobalTurnOnSync())
}
view.swipe_refresh.setOnRefreshListener {
interactor.onRequestSync()

@ -17,7 +17,6 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
@Suppress("TooManyFunctions")
interface HistoryController {
@ -101,7 +100,7 @@ class DefaultHistoryController(
}
override fun handleShare(item: HistoryItem) {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
HistoryFragmentDirections.actionGlobalShareFragment(
data = arrayOf(ShareData(url = item.url, title = item.title))
)
@ -117,7 +116,7 @@ class DefaultHistoryController(
}
override fun handleEnterRecentlyClosed() {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
HistoryFragmentDirections.actionGlobalRecentlyClosed(),
NavOptions.Builder().setPopUpTo(R.id.recentlyClosedFragment, true).build()
)

@ -35,6 +35,7 @@ import mozilla.components.service.fxa.sync.SyncReason
import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavHostActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.addons.showSnackBar
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
@ -46,7 +47,6 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.setTextColor
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.library.LibraryPageFragment
import org.mozilla.fenix.utils.allowUndo
@ -105,7 +105,6 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
view.historyLayout,
historyInteractor
)
showToolbar(getString(R.string.library_history))
return view
}
@ -162,6 +161,8 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
override fun onResume() {
super.onResume()
(activity as NavHostActivity).getSupportActionBarAndInflateIfNecessary().show()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {

@ -19,7 +19,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
@Suppress("TooManyFunctions")
interface RecentlyClosedController {
@ -76,7 +75,7 @@ class DefaultRecentlyClosedController(
}
override fun handleNavigateToHistory() {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
RecentlyClosedFragmentDirections.actionGlobalHistoryFragment(),
NavOptions.Builder().setPopUpTo(R.id.historyFragment, true).build()
)
@ -95,7 +94,7 @@ class DefaultRecentlyClosedController(
override fun handleShare(tabs: Set<RecoverableTab>) {
val shareData = tabs.map { ShareData(url = it.url, title = it.title) }
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
RecentlyClosedFragmentDirections.actionGlobalShareFragment(
data = shareData.toTypedArray()
)

@ -7,7 +7,6 @@ package org.mozilla.fenix.nimbus.view
import androidx.navigation.NavController
import mozilla.components.service.nimbus.ui.NimbusExperimentsAdapterDelegate
import org.mozilla.experiments.nimbus.AvailableExperiment
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.nimbus.NimbusExperimentsFragmentDirections
/**
@ -24,6 +23,6 @@ class NimbusExperimentsView(
experimentName = experiment.userFacingName
)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
}

@ -1,59 +0,0 @@
/* 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() }
}
}

@ -413,6 +413,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
} else null
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
private fun createQrFeature(): QrFeature {
return QrFeature(
requireContext(),
@ -448,6 +450,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
)
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
@ -534,6 +538,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
}
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19919
private fun launchVoiceSearch() {
// Note if a user disables speech while the app is on the search fragment
// the voice button will still be available and *will* cause a crash if tapped,

@ -26,6 +26,8 @@ class PairFragment : Fragment(R.layout.fragment_pair), UserInteractionHandler {
private val qrFeature = ViewBoundFeatureWrapper<QrFeature>()
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

@ -46,7 +46,6 @@ import org.mozilla.fenix.experiments.FeatureId
import org.mozilla.fenix.ext.application
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.navigateToNotificationsSettings
import org.mozilla.fenix.ext.requireComponents
@ -478,6 +477,8 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19919
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
@ -496,7 +497,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private fun navigateFromSettings(directions: NavDirections) {
view?.findNavController()?.let { navController ->
if (navController.currentDestination?.id == R.id.settingsFragment) {
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
}
}

@ -16,7 +16,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
@ -33,7 +32,7 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
private val exceptionsClickListener = Preference.OnPreferenceClickListener {
val directions =
TrackingProtectionFragmentDirections.actionTrackingProtectionFragmentToExceptionsFragment()
requireView().findNavController().navigateBlockingForAsyncNavGraph(directions)
requireView().findNavController().navigate(directions)
true
}
private lateinit var customCookies: CheckBoxPreference

@ -22,7 +22,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.crashes.CrashListActivity
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -180,7 +179,7 @@ class AboutFragment : Fragment(), AboutPageListener {
private fun openLibrariesPage() {
val navController = findNavController()
navController.navigateBlockingForAsyncNavGraph(R.id.action_aboutFragment_to_aboutLibrariesFragment)
navController.navigate(R.id.action_aboutFragment_to_aboutLibrariesFragment)
}
override fun onAboutItemClicked(item: AboutItem) {

@ -26,7 +26,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -60,7 +59,7 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
private fun navigateToPairFragment() {
val directions = TurnOnSyncFragmentDirections.actionTurnOnSyncFragmentToPairFragment()
requireView().findNavController().navigateBlockingForAsyncNavGraph(directions)
requireView().findNavController().navigate(directions)
requireComponents.analytics.metrics.track(Event.SyncAuthScanPairing)
}

@ -29,7 +29,6 @@ import mozilla.components.service.fxa.SyncEngine
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.runIfFragmentIsAttached
@ -130,12 +129,12 @@ class CreditCardsSettingFragment : BiometricPromptPreferenceFragment() {
loggedInTitle = requireContext()
.getString(R.string.preferences_credit_cards_sync_cards),
onSignInToSyncClicked = {
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
NavGraphDirections.actionGlobalTurnOnSync()
)
},
onReconnectClicked = {
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
CreditCardsSettingFragmentDirections.actionGlobalAccountProblemFragment()
)
}
@ -169,7 +168,7 @@ class CreditCardsSettingFragment : BiometricPromptPreferenceFragment() {
if (hasCreditCards) {
verifyCredentialsOrShowSetupWarning(requireContext(), creditCardPreferences)
} else {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
CreditCardsSettingFragmentDirections
.actionCreditCardsSettingFragmentToCreditCardEditorFragment()
)
@ -240,7 +239,7 @@ class CreditCardsSettingFragment : BiometricPromptPreferenceFragment() {
val directions =
CreditCardsSettingFragmentDirections
.actionCreditCardsSettingFragmentToCreditCardsManagementFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
companion object {

@ -6,7 +6,6 @@ package org.mozilla.fenix.settings.creditcards.controller
import androidx.navigation.NavController
import mozilla.components.concept.storage.CreditCard
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.settings.creditcards.CreditCardsManagementFragment
import org.mozilla.fenix.settings.creditcards.CreditCardsManagementFragmentDirections
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
@ -44,7 +43,7 @@ class DefaultCreditCardsManagementController(
}
private fun navigateToCreditCardEditor(creditCard: CreditCard? = null) {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
CreditCardsManagementFragmentDirections
.actionCreditCardsManagementFragmentToCreditCardEditorFragment(
creditCard = creditCard

@ -28,7 +28,6 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -200,7 +199,7 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da
// If the user deletes all open tabs we need to make sure we remove
// the BrowserFragment from the backstack.
popBackStack(R.id.homeFragment, false)
navigateBlockingForAsyncNavGraph(DeleteBrowsingDataFragmentDirections.actionGlobalSettingsFragment())
navigate(DeleteBrowsingDataFragmentDirections.actionGlobalSettingsFragment())
}
}
}

@ -8,7 +8,6 @@ import androidx.navigation.NavController
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.logins.LoginsAction
import org.mozilla.fenix.settings.logins.LoginsFragmentStore
@ -41,7 +40,7 @@ class LoginsListController(
fun handleItemClicked(item: SavedLogin) {
loginsFragmentStore.dispatch(LoginsAction.LoginSelected(item))
metrics.track(Event.OpenOneLogin)
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(item.guid)
)
}

@ -20,7 +20,6 @@ import mozilla.components.service.sync.logins.LoginsStorageException
import mozilla.components.service.sync.logins.NoSuchRecordException
import mozilla.components.service.sync.logins.SyncableLoginsStorage
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.settings.logins.LoginsAction
import org.mozilla.fenix.settings.logins.LoginsFragmentStore
import org.mozilla.fenix.settings.logins.fragment.EditLoginFragmentDirections
@ -84,7 +83,7 @@ open class SavedLoginsStorageController(
EditLoginFragmentDirections.actionEditLoginFragmentToLoginDetailFragment(
loginId
)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
}
saveLoginJob?.invokeOnCompletion {

@ -33,7 +33,6 @@ import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.redirectToReAuth
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
@ -201,7 +200,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
LoginDetailFragmentDirections.actionLoginDetailFragmentToEditLoginFragment(
login!!
)
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
private fun displayDeleteLoginDialog() {

@ -27,7 +27,6 @@ import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.secure
@ -135,12 +134,12 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
onSignInToSyncClicked = {
val directions =
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
},
onReconnectClicked = {
val directions =
SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
)
@ -213,19 +212,19 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
context?.components?.analytics?.metrics?.track(Event.OpenLogins)
val directions =
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginsListFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
private fun navigateToSaveLoginSettingFragment() {
val directions =
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToSavedLoginsSettingFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
private fun navigateToLoginExceptionFragment() {
val directions =
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginExceptionsFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
companion object {

@ -17,7 +17,6 @@ import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
import mozilla.components.support.base.feature.OnNeedToRequestPermissions
import mozilla.components.support.ktx.kotlin.getOrigin
import org.mozilla.fenix.components.PermissionStorage
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
import org.mozilla.fenix.settings.toggle
@ -198,6 +197,6 @@ class DefaultQuickSettingsController(
private fun navigateToManagePhoneFeature(phoneFeature: PhoneFeature) {
val directions = QuickSettingsSheetDialogFragmentDirections
.actionGlobalSitePermissionsManagePhoneFeature(phoneFeature)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
}

@ -55,6 +55,8 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
private var tryToRequestPermissions: Boolean = false
private val args by navArgs<QuickSettingsSheetDialogFragmentArgs>()
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,

@ -38,7 +38,6 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.utils.allowUndo
class RadioSearchEngineListPreference @JvmOverloads constructor(
@ -147,7 +146,7 @@ class RadioSearchEngineListPreference @JvmOverloads constructor(
val directions = SearchEngineFragmentDirections
.actionSearchEngineFragmentToEditCustomSearchEngineFragment(engine.id)
Navigation.findNavController(view).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(view).navigate(directions)
}
private fun deleteSearchEngine(

@ -14,7 +14,6 @@ import androidx.preference.SwitchPreference
import mozilla.components.support.ktx.android.view.hideKeyboard
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.settings.SharedPreferenceUpdater
@ -111,7 +110,7 @@ class SearchEngineFragment : PreferenceFragmentCompat() {
getPreferenceKey(R.string.pref_key_add_search_engine) -> {
val directions = SearchEngineFragmentDirections
.actionSearchEngineFragmentToAddSearchEngineFragment()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
}

@ -21,7 +21,6 @@ import mozilla.components.concept.engine.permission.SitePermissions
import mozilla.components.support.ktx.kotlin.stripDefaultPort
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -163,6 +162,6 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() {
phoneFeature = phoneFeature,
sitePermissions = sitePermissions
)
requireView().findNavController().navigateBlockingForAsyncNavGraph(directions)
requireView().findNavController().navigate(directions)
}
}

@ -12,7 +12,6 @@ import androidx.preference.PreferenceFragmentCompat
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -43,7 +42,7 @@ class SitePermissionsFragment : PreferenceFragmentCompat() {
exceptionsCategory.onPreferenceClickListener = OnPreferenceClickListener {
val directions = SitePermissionsFragmentDirections.actionSitePermissionsToExceptions()
Navigation.findNavController(requireView()).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(requireView()).navigate(directions)
true
}
}
@ -77,6 +76,6 @@ class SitePermissionsFragment : PreferenceFragmentCompat() {
requireComponents.analytics.metrics.track(Event.AutoPlaySettingVisited)
}
Navigation.findNavController(requireView()).navigateBlockingForAsyncNavGraph(directions)
Navigation.findNavController(requireView()).navigate(directions)
}
}

@ -31,7 +31,6 @@ import mozilla.components.support.ktx.kotlin.isExtensionUrl
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.share.listadapters.AppShareOption
@ -122,7 +121,7 @@ class DefaultShareController(
override fun handleAddNewDevice() {
val directions = ShareFragmentDirections.actionShareFragmentToAddNewDeviceFragment()
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
override fun handleShareToDevice(device: Device) {

@ -13,7 +13,6 @@ import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.observe
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.fragment_share.view.*
@ -26,8 +25,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.getRootView
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.share.listadapters.AppShareOption
import org.mozilla.fenix.share.listadapters.SyncShareOption
class ShareFragment : AppCompatDialogFragment() {
@ -113,13 +110,13 @@ class ShareFragment : AppCompatDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.devicesList.observe<List<SyncShareOption>>(viewLifecycleOwner) { devicesShareOptions ->
viewModel.devicesList.observe(viewLifecycleOwner) { devicesShareOptions ->
shareToAccountDevicesView.setShareTargets(devicesShareOptions)
}
viewModel.appsList.observe<List<AppShareOption>>(viewLifecycleOwner) { appsToShareTo ->
viewModel.appsList.observe(viewLifecycleOwner) { appsToShareTo ->
shareToAppsView.setShareTargets(appsToShareTo)
}
viewModel.recentAppsList.observe<List<AppShareOption>>(viewLifecycleOwner) { appsToShareTo ->
viewModel.recentAppsList.observe(viewLifecycleOwner) { appsToShareTo ->
shareToAppsView.setRecentShareTargets(appsToShareTo)
}
}

@ -19,7 +19,6 @@ import mozilla.components.feature.syncedtabs.view.SyncedTabsView
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.sync.SyncedTabsAdapter.AdapterItem
@ -66,7 +65,7 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item
errorItem.navController?.let { navController ->
itemView.sync_tabs_error_cta_button.visibility = VISIBLE
itemView.sync_tabs_error_cta_button.setOnClickListener {
navController.navigateBlockingForAsyncNavGraph(NavGraphDirections.actionGlobalTurnOnSync())
navController.navigate(NavGraphDirections.actionGlobalTurnOnSync())
}
}
}

@ -24,7 +24,6 @@ import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.tabstray.ext.getTabSessionState
import kotlin.coroutines.CoroutineContext
@ -122,17 +121,17 @@ class DefaultNavigationInteractor(
} else {
TabsTrayFragmentDirections.actionGlobalTurnOnSync()
}
navController.navigateBlockingForAsyncNavGraph(direction)
navController.navigate(direction)
}
override fun onTabSettingsClicked() {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
TabsTrayFragmentDirections.actionGlobalTabSettingsFragment()
)
}
override fun onOpenRecentlyClosedClicked() {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
TabsTrayFragmentDirections.actionGlobalRecentlyClosed()
)
metrics.track(Event.RecentlyClosedTabsOpened)
@ -145,7 +144,7 @@ class DefaultNavigationInteractor(
val directions = TabsTrayFragmentDirections.actionGlobalShareFragment(
data = data.toTypedArray()
)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
override fun onShareTabsOfTypeClicked(private: Boolean) {
@ -156,7 +155,7 @@ class DefaultNavigationInteractor(
val directions = TabsTrayFragmentDirections.actionGlobalShareFragment(
data = data.toTypedArray()
)
navController.navigateBlockingForAsyncNavGraph(directions)
navController.navigate(directions)
}
@OptIn(ExperimentalCoroutinesApi::class)

@ -18,7 +18,6 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.home.HomeFragment
interface TabsTrayController {
@ -75,7 +74,7 @@ class DefaultTabsTrayController(
override fun handleOpeningNewTab(isPrivate: Boolean) {
val startTime = profiler?.getProfilerTime()
browsingModeManager.mode = BrowsingMode.fromBoolean(isPrivate)
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
TabsTrayFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
navigationInteractor.onTabTrayDismissed()
profiler?.addMarker(
@ -99,7 +98,7 @@ class DefaultTabsTrayController(
if (navController.currentDestination?.id == R.id.browserFragment) {
return
} else if (!navController.popBackStack(R.id.browserFragment, false)) {
navController.navigateBlockingForAsyncNavGraph(R.id.browserFragment)
navController.navigate(R.id.browserFragment)
}
}

@ -38,7 +38,6 @@ import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeScreenViewModel
@ -383,7 +382,7 @@ class TabsTrayFragment : AppCompatDialogFragment() {
internal fun navigateToHomeAndDeleteSession(sessionId: String) {
homeViewModel.sessionToDelete = sessionId
val directions = NavGraphDirections.actionGlobalHome()
findNavController().navigateBlockingForAsyncNavGraph(directions)
findNavController().navigate(directions)
}
@VisibleForTesting
@ -415,7 +414,7 @@ class TabsTrayFragment : AppCompatDialogFragment() {
.make(requireView())
.message(tabSize, isNewCollection)
.anchorWithAction(anchor) {
findNavController().navigateBlockingForAsyncNavGraph(
findNavController().navigate(
TabsTrayFragmentDirections.actionGlobalHome(
focusOnAddressBar = false,
focusOnCollection = collectionToSelect.orDefault()

@ -62,6 +62,8 @@ class VoiceSearchActivity : AppCompatActivity() {
/**
* Displays a speech recognizer popup that listens for input from the user.
*/
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19919
private fun displaySpeechRecognizer() {
val intentSpeech = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(
@ -80,6 +82,8 @@ class VoiceSearchActivity : AppCompatActivity() {
startActivityForResult(intentSpeech, SPEECH_REQUEST_CODE)
}
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19919
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

@ -23,5 +23,6 @@
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"/>
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</LinearLayout>

@ -20,6 +20,7 @@ import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@ -166,6 +167,7 @@ class HomeActivityTest {
assertFalse(activity.shouldStartOnHome(startingIntent))
}
@Ignore("failed after library upgrade, see: https://github.com/mozilla-mobile/fenix/issues/19921")
@Test
fun `WHEN onCreate is called THEN the duration is measured`() {
assertFalse(PerfStartup.homeActivityOnCreate.testHasValue()) // sanity check.

@ -18,6 +18,7 @@ import mozilla.components.support.utils.toSafeIntent
import org.junit.Before
import org.junit.Test
import org.junit.Assert.assertTrue
import org.junit.runner.RunWith
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.Events.appOpenedAllStartupKeys.firstFramePreDrawNanos
import org.mozilla.fenix.GleanMetrics.Events.appOpenedAllStartupKeys.hasSavedInstanceState
@ -33,7 +34,9 @@ import org.mozilla.fenix.components.metrics.Event.AppAllStartup.Type.COLD
import org.mozilla.fenix.components.metrics.Event.AppAllStartup.Type.WARM
import org.mozilla.fenix.components.metrics.Event.AppAllStartup.Type.HOT
import org.mozilla.fenix.components.metrics.Event.AppAllStartup.Type.ERROR
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
class AppStartupTelemetryTest {
@MockK

@ -18,7 +18,10 @@ import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.crash.service.CrashReporterService
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
class BreadcrumbRecorderTest {
@Test

@ -12,9 +12,7 @@ import io.mockk.verify
import mozilla.components.lib.crash.Crash
import mozilla.components.support.test.ext.joinBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.R
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.components.metrics.Event
@ -23,9 +21,6 @@ import org.mozilla.fenix.utils.Settings
class CrashReporterControllerTest {
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
private lateinit var components: Components
private lateinit var crash: Crash
private lateinit var sessionId: String

@ -18,16 +18,11 @@ import io.mockk.mockkStatic
import io.mockk.verify
import io.sentry.Sentry
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.components.isSentryEnabled
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
class NavControllerTest {
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
private val currentDestId = 4
@MockK(relaxUnitFun = true) private lateinit var navController: NavController
@MockK private lateinit var navDirections: NavDirections

@ -111,6 +111,8 @@ class ViewTest {
}
@Test
@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19929
fun `getKeyboardHeight accounts for status bar and navigation bar`() {
every { view.getWindowVisibleDisplayFrame() } returns Rect(0, 50, 1000, 500)
every { view.rootView.height } returns 1000

@ -1,43 +0,0 @@
/* 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,19 +7,13 @@ package org.mozilla.fenix.helpers
import org.mozilla.fenix.FenixApplication
import org.mozilla.fenix.R
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
* because our standard application fails to initialize in Robolectric with exceptions like:
* "Crash handler service must run in a separate process".
*/
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()
class FenixRobolectricTestApplication : FenixApplication() {
override fun onCreate() {
super.onCreate()
@ -43,19 +37,4 @@ class FenixRobolectricTestApplication : FenixApplication(), TestLifecycleApplica
// https://github.com/mozilla-mobile/fenix/pull/15646#issuecomment-709411141
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,7 +39,6 @@ import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.R
import org.mozilla.fenix.components.Analytics
import org.mozilla.fenix.components.TabCollectionStorage
@ -114,9 +113,6 @@ class DefaultSessionControlControllerTest {
private lateinit var store: BrowserStore
private lateinit var controller: DefaultSessionControlController
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@Before
fun setup() {
store = BrowserStore(

@ -23,8 +23,6 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
@OptIn(ExperimentalCoroutinesApi::class)
class RecentTabControllerTest {
@ -34,9 +32,6 @@ class RecentTabControllerTest {
@get:Rule
val coroutinesTestRule = MainCoroutineRule(testDispatcher)
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
private val navController: NavController = mockk(relaxed = true)
private val selectTabUseCase: TabsUseCases = mockk(relaxed = true)
@ -71,7 +66,7 @@ class RecentTabControllerTest {
verify {
selectTabUseCase.selectTab.invoke(tab.id)
navController.navigateBlockingForAsyncNavGraph(R.id.browserFragment)
navController.navigate(R.id.browserFragment)
}
}

@ -31,11 +31,9 @@ import mozilla.components.feature.tabs.TabsUseCases
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.Services
@ -93,9 +91,6 @@ class BookmarkControllerTest {
BookmarkNodeType.FOLDER, BookmarkRoot.Root.id, null, 0, BookmarkRoot.Root.name, null, null
)
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@Before
fun setup() {
every { homeActivity.components.services } returns services

@ -32,7 +32,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.directionsEq
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.optionsEq
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -156,7 +155,7 @@ class DefaultRecentlyClosedControllerTest {
controller.handleNavigateToHistory()
verify {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
directionsEq(
RecentlyClosedFragmentDirections.actionGlobalHistoryFragment()
),
@ -191,7 +190,7 @@ class DefaultRecentlyClosedControllerTest {
controller.handleShare(item)
verify {
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
directionsEq(
RecentlyClosedFragmentDirections.actionGlobalShareFragment(
data = arrayOf(ShareData(url = item.url, title = item.title))
@ -212,7 +211,7 @@ class DefaultRecentlyClosedControllerTest {
ShareData(title = tabs[0].title, url = tabs[0].url),
ShareData(title = tabs[1].title, url = tabs[1].url)
)
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
directionsEq(RecentlyClosedFragmentDirections.actionGlobalShareFragment(data))
)
}

@ -28,11 +28,9 @@ import mozilla.components.support.test.middleware.CaptureActionsMiddleware
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
@ -61,9 +59,6 @@ class SearchDialogControllerTest {
private lateinit var middleware: CaptureActionsMiddleware<BrowserState, BrowserAction>
private lateinit var browserStore: BrowserStore
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@Before
fun setUp() {
MockKAnnotations.init(this)

@ -13,7 +13,10 @@ import io.mockk.mockk
import io.mockk.verify
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
class OnSharedPreferenceChangeListenerTest {
private lateinit var sharedPrefs: SharedPreferences

@ -13,16 +13,11 @@ import io.mockk.verify
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.R
class AccountSettingsInteractorTest {
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@Test
fun onSyncNow() {
var ranSyncNow = false

@ -21,7 +21,6 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.robolectric.Robolectric
@ -92,6 +91,6 @@ class CreditCardsSettingFragmentTest {
manageCardsPreference?.performClick()
verify { navController.navigateBlockingForAsyncNavGraph(directions) }
verify { navController.navigate(directions) }
}
}

@ -12,10 +12,8 @@ import mozilla.components.concept.storage.CreditCard
import mozilla.components.concept.storage.CreditCardNumber
import mozilla.components.support.utils.CreditCardNetworkType
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardsManagementController
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
class DefaultCreditCardsManagementControllerTest {
@ -23,9 +21,6 @@ class DefaultCreditCardsManagementControllerTest {
private lateinit var controller: DefaultCreditCardsManagementController
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@Before
fun setup() {
controller = spyk(

@ -13,21 +13,21 @@ import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.feature.pwa.WebAppUseCases
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.utils.Settings
@ExperimentalCoroutinesApi
@RunWith(FenixRobolectricTestRunner::class)
class PwaOnboardingObserverTest {
private lateinit var store: BrowserStore
@ -37,11 +37,6 @@ class PwaOnboardingObserverTest {
private lateinit var settings: Settings
private lateinit var webAppUseCases: WebAppUseCases
private val testDispatcher = TestCoroutineDispatcher()
@get:Rule
val coroutinesTestRule = MainCoroutineRule(testDispatcher)
@Before
fun setUp() {
store = BrowserStore(

@ -6,6 +6,7 @@ package org.mozilla.fenix.tabstray
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.NavOptions
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
@ -24,15 +25,12 @@ import mozilla.components.concept.base.profiler.Profiler
import mozilla.components.concept.tabstray.Tab
import mozilla.components.feature.tabs.TabsUseCases
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.HomeFragment
@ -76,9 +74,6 @@ class DefaultTabsTrayControllerTest {
private lateinit var controller: DefaultTabsTrayController
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@Before
fun setup() {
MockKAnnotations.init(this)
@ -122,7 +117,7 @@ class DefaultTabsTrayControllerTest {
verifyOrder {
profiler.getProfilerTime()
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
TabsTrayFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
)
navigationInteractor.onTabTrayDismissed()
@ -157,7 +152,7 @@ class DefaultTabsTrayControllerTest {
verifyOrder {
profiler.getProfilerTime()
navController.navigateBlockingForAsyncNavGraph(
navController.navigate(
TabsTrayFragmentDirections.actionGlobalHome(focusOnAddressBar = true)
)
navigationInteractor.onTabTrayDismissed()
@ -219,9 +214,9 @@ class DefaultTabsTrayControllerTest {
verify { dismissTray() }
verify(exactly = 0) { navController.popBackStack() }
verify(exactly = 0) { navController.popBackStack(any(), any()) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(any<Int>()) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(any<NavDirections>()) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(any(), any()) }
verify(exactly = 0) { navController.navigate(any<Int>()) }
verify(exactly = 0) { navController.navigate(any<NavDirections>()) }
verify(exactly = 0) { navController.navigate(any<NavDirections>(), any<NavOptions>()) }
}
@Test
@ -233,9 +228,9 @@ class DefaultTabsTrayControllerTest {
verify { dismissTray() }
verify { navController.popBackStack(R.id.browserFragment, false) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(any<Int>()) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(any<NavDirections>()) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(any(), any()) }
verify(exactly = 0) { navController.navigate(any<Int>()) }
verify(exactly = 0) { navController.navigate(any<NavDirections>()) }
verify(exactly = 0) { navController.navigate(any<NavDirections>(), any<NavOptions>()) }
}
@Test
@ -247,7 +242,7 @@ class DefaultTabsTrayControllerTest {
verify { dismissTray() }
verify { navController.popBackStack(R.id.browserFragment, false) }
verify { navController.navigateBlockingForAsyncNavGraph(R.id.browserFragment) }
verify { navController.navigate(R.id.browserFragment) }
}
@Test
@ -258,7 +253,7 @@ class DefaultTabsTrayControllerTest {
verify { dismissTray() }
verify(exactly = 1) { navController.popBackStack(R.id.browserFragment, false) }
verify(exactly = 0) { navController.navigateBlockingForAsyncNavGraph(R.id.browserFragment) }
verify(exactly = 0) { navController.navigate(R.id.browserFragment) }
}
@Test

@ -35,7 +35,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.collections.CollectionsDialog
import org.mozilla.fenix.collections.show
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.helpers.DisableNavGraphProviderAssertionRule
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
@ -60,9 +59,6 @@ class NavigationInteractorTest {
private val testDispatcher = TestCoroutineDispatcher()
@get:Rule
val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule()
@get:Rule
val coroutinesTestRule = MainCoroutineRule(testDispatcher)

@ -48,7 +48,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.HomeScreenViewModel
@ -315,7 +314,7 @@ class TabsTrayFragmentTest {
fragment.navigateToHomeAndDeleteSession("test")
verify { viewModel.sessionToDelete = "test" }
verify { navController.navigateBlockingForAsyncNavGraph(NavGraphDirections.actionGlobalHome()) }
verify { navController.navigate(NavGraphDirections.actionGlobalHome()) }
} finally {
unmockkStatic("org.mozilla.fenix.ext.NavControllerKt")
unmockkStatic("androidx.navigation.fragment.FragmentKt")

@ -17,7 +17,7 @@ object Versions {
const val detekt = "1.17.1"
const val jna = "5.6.0"
const val androidx_appcompat = "1.2.0"
const val androidx_appcompat = "1.3.0"
const val androidx_biometric = "1.1.0"
const val androidx_coordinator_layout = "1.1.0"
const val androidx_constraint_layout = "2.0.4"
@ -25,7 +25,7 @@ object Versions {
const val androidx_legacy = "1.0.0"
const val androidx_annotation = "1.1.0"
const val androidx_lifecycle = "2.2.0"
const val androidx_fragment = "1.2.5"
const val androidx_fragment = "1.3.4"
const val androidx_navigation = "2.3.3"
const val androidx_recyclerview = "1.2.0-beta01"
const val androidx_core = "1.3.2"

@ -122,9 +122,6 @@ mozilla-detekt-rules:
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
MozillaUseLazyMonitored:
active: true
MozillaNavigateCheck:
active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
empty-blocks:
active: true

@ -8,7 +8,6 @@ import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.RuleSet
import io.gitlab.arturbosch.detekt.api.RuleSetProvider
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.MozillaRunBlockingCheck
import org.mozilla.fenix.detektrules.perf.MozillaUseLazyMonitored
@ -24,7 +23,6 @@ class CustomRulesetProvider : RuleSetProvider {
MozillaCorrectUnitTestRunner(config),
MozillaRunBlockingCheck(config),
MozillaUseLazyMonitored(config),
MozillaNavigateCheck(config)
)
)
}

@ -1,50 +0,0 @@
/* 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…
Cancel
Save