For #23046 - Align detekt config between Fenix and Android Components

Co-authored-by: Gabriel Luong <gabriel.luong@gmail.com>
upstream-sync
Brais Gabín 2 years ago committed by mergify[bot]
parent 57238fa5ca
commit 1f633edd7d

@ -21,6 +21,33 @@
} }
} }
}, },
"messaging": {
"description": "Configuration for the messaging system.\n\nIn practice this is a set of growable lookup tables for the\nmessage controller to piece together.\n",
"hasExposure": true,
"exposureDescription": "",
"variables": {
"actions": {
"type": "json",
"description": "A growable map of action URLs."
},
"message-under-experiment": {
"type": "string",
"description": "Id or prefix of the message under experiment."
},
"messages": {
"type": "json",
"description": "A growable collection of messages"
},
"styles": {
"type": "json",
"description": "A map of styles to configure message appearance.\n"
},
"triggers": {
"type": "json",
"description": "A collection of out the box trigger expressions. Each entry maps to a valid JEXL expression.\n"
}
}
},
"nimbus-validation": { "nimbus-validation": {
"description": "A feature that does not correspond to an application feature suitable for showing that Nimbus is working. This should never be used in production.", "description": "A feature that does not correspond to an application feature suitable for showing that Nimbus is working. This should never be used in production.",
"hasExposure": true, "hasExposure": true,

@ -342,16 +342,15 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
// To re-enable this, we need to do so in a way that won't interfere with any startup operations // To re-enable this, we need to do so in a way that won't interfere with any startup operations
// which acquire reserved+ sqlite lock. Currently, Fennec migrations need to write to storage // which acquire reserved+ sqlite lock. Currently, Fennec migrations need to write to storage
// on startup, and since they run in a background service we can't simply order these operations. // on startup, and since they run in a background service we can't simply order these operations.
// @OptIn(DelicateCoroutinesApi::class) // GlobalScope usage
@OptIn(DelicateCoroutinesApi::class) // GlobalScope usage // private fun runStorageMaintenance() {
private fun runStorageMaintenance() { // GlobalScope.launch(Dispatchers.IO) {
GlobalScope.launch(Dispatchers.IO) { // // Bookmarks and history storage sit on top of the same db file so we only need to
// Bookmarks and history storage sit on top of the same db file so we only need to // // run maintenance on one - arbitrarily using bookmarks.
// run maintenance on one - arbitrarily using bookmarks. // // components.core.bookmarksStorage.runMaintenance()
components.core.bookmarksStorage.runMaintenance() // }
} // settings().lastPlacesStorageMaintenance = System.currentTimeMillis()
settings().lastPlacesStorageMaintenance = System.currentTimeMillis() // }
}
protected open fun setupLeakCanary() { protected open fun setupLeakCanary() {
// no-op, LeakCanary is disabled by default // no-op, LeakCanary is disabled by default

@ -23,8 +23,10 @@ class FenixLogSink(private val logsDebug: Boolean = true) : LogSink {
throwable: Throwable?, throwable: Throwable?,
message: String? message: String?
) { ) {
if (priority == Log.Priority.DEBUG && !logsDebug) if (priority == Log.Priority.DEBUG && !logsDebug) {
return return
}
androidLogSink.log(priority, tag, throwable, message) androidLogSink.log(priority, tag, throwable, message)
} }
} }

@ -53,9 +53,11 @@ class CollectionCreationBottomBarView(
context.getString(R.string.create_collection_save_to_collection_empty) context.getString(R.string.create_collection_save_to_collection_empty)
} else { } else {
context.getString( context.getString(
if (state.selectedTabs.size == 1) if (state.selectedTabs.size == 1) {
R.string.create_collection_save_to_collection_tab_selected else R.string.create_collection_save_to_collection_tab_selected
R.string.create_collection_save_to_collection_tabs_selected, } else {
R.string.create_collection_save_to_collection_tabs_selected
},
state.selectedTabs.size state.selectedTabs.size
) )
} }

@ -122,12 +122,19 @@ class CollectionCreationView(
binding.selectAllButton.apply { binding.selectAllButton.apply {
val allSelected = state.selectedTabs.size == state.tabs.size val allSelected = state.selectedTabs.size == state.tabs.size
text =
if (allSelected) context.getString(R.string.create_collection_deselect_all) text = if (allSelected) {
else context.getString(R.string.create_collection_select_all) context.getString(R.string.create_collection_deselect_all)
} else {
context.getString(R.string.create_collection_select_all)
}
setOnClickListener { setOnClickListener {
if (allSelected) interactor.deselectAllTapped() if (allSelected) {
else interactor.selectAllTapped() interactor.deselectAllTapped()
} else {
interactor.selectAllTapped()
}
} }
} }

@ -9,14 +9,12 @@ import android.content.SharedPreferences
import android.os.StrictMode import android.os.StrictMode
import androidx.annotation.GuardedBy import androidx.annotation.GuardedBy
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.Dispatchers
import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.lib.crash.CrashReporter import mozilla.components.lib.crash.CrashReporter
import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.log.logger.Logger
import org.mozilla.fenix.perf.StrictModeManager import org.mozilla.fenix.perf.StrictModeManager
import kotlin.coroutines.CoroutineContext
/** /**
* Miscellaneous FxA-related abnormalities. * Miscellaneous FxA-related abnormalities.
@ -51,13 +49,11 @@ internal abstract class AbnormalFxaEvent : Exception() {
* See [AbnormalFxaEvent] for types of abnormal events this class detects. * See [AbnormalFxaEvent] for types of abnormal events this class detects.
* *
* @param crashReporter An instance of [CrashReporter] used for reporting detected abnormalities. * @param crashReporter An instance of [CrashReporter] used for reporting detected abnormalities.
* @param coroutineContext A [CoroutineContext] used for executing async tasks. Defaults to [Dispatchers.IO].
*/ */
class AccountAbnormalities( class AccountAbnormalities(
context: Context, context: Context,
private val crashReporter: CrashReporter, private val crashReporter: CrashReporter,
strictMode: StrictModeManager, strictMode: StrictModeManager,
private val coroutineContext: CoroutineContext = Dispatchers.IO
) : AccountObserver { ) : AccountObserver {
companion object { companion object {
private const val PREF_FXA_ABNORMALITIES = "fxa_abnormalities" private const val PREF_FXA_ABNORMALITIES = "fxa_abnormalities"

@ -33,8 +33,11 @@ object MetricsUtils {
val isCustom = engine.type == SearchEngine.Type.CUSTOM val isCustom = engine.type == SearchEngine.Type.CUSTOM
val engineSource = val engineSource =
if (isShortcut) Event.PerformedSearch.EngineSource.Shortcut(engine, isCustom) if (isShortcut) {
else Event.PerformedSearch.EngineSource.Default(engine, isCustom) Event.PerformedSearch.EngineSource.Shortcut(engine, isCustom)
} else {
Event.PerformedSearch.EngineSource.Default(engine, isCustom)
}
return when (searchAccessPoint) { return when (searchAccessPoint) {
SearchAccessPoint.SUGGESTION -> Event.PerformedSearch( SearchAccessPoint.SUGGESTION -> Event.PerformedSearch(

@ -302,12 +302,16 @@ open class DefaultToolbarMenu(
val settingsItem = BrowserMenuHighlightableItem( val settingsItem = BrowserMenuHighlightableItem(
label = context.getString(R.string.browser_menu_settings), label = context.getString(R.string.browser_menu_settings),
startImageResource = R.drawable.mozac_ic_settings, startImageResource = R.drawable.mozac_ic_settings,
iconTintColorResource = if (hasAccountProblem) iconTintColorResource = if (hasAccountProblem) {
ThemeManager.resolveAttribute(R.attr.syncDisconnected, context) else ThemeManager.resolveAttribute(R.attr.syncDisconnected, context)
primaryTextColor(), } else {
textColorResource = if (hasAccountProblem) primaryTextColor()
ThemeManager.resolveAttribute(R.attr.textPrimary, context) else },
primaryTextColor(), textColorResource = if (hasAccountProblem) {
ThemeManager.resolveAttribute(R.attr.textPrimary, context)
} else {
primaryTextColor()
},
highlight = BrowserMenuHighlight.HighPriority( highlight = BrowserMenuHighlight.HighPriority(
endImageResource = R.drawable.ic_sync_disconnected, endImageResource = R.drawable.ic_sync_disconnected,
backgroundTint = context.getColorFromAttr(R.attr.syncDisconnectedBackground), backgroundTint = context.getColorFromAttr(R.attr.syncDisconnectedBackground),

@ -119,7 +119,7 @@ private fun ThumbnailImage(
@Preview @Preview
@Composable @Composable
fun ThumbnailCardPreview() { private fun ThumbnailCardPreview() {
ThumbnailCard( ThumbnailCard(
url = "https://mozilla.com", url = "https://mozilla.com",
key = "123", key = "123",

@ -100,13 +100,17 @@ class DynamicDownloadDialogBehavior<V : View>(
) { ) {
if (shouldSnapAfterScroll || type == ViewCompat.TYPE_NON_TOUCH) { if (shouldSnapAfterScroll || type == ViewCompat.TYPE_NON_TOUCH) {
if (expanded) { if (expanded) {
if (child.translationY >= bottomToolbarHeight / 2) if (child.translationY >= bottomToolbarHeight / 2) {
animateSnap(child, SnapDirection.DOWN) animateSnap(child, SnapDirection.DOWN)
else animateSnap(child, SnapDirection.UP) } else {
animateSnap(child, SnapDirection.UP)
}
} else { } else {
if (child.translationY < (bottomToolbarHeight + child.height.toFloat() / 2)) if (child.translationY < (bottomToolbarHeight + child.height.toFloat() / 2)) {
animateSnap(child, SnapDirection.UP) animateSnap(child, SnapDirection.UP)
else animateSnap(child, SnapDirection.DOWN) } else {
animateSnap(child, SnapDirection.DOWN)
}
} }
} }
} }
@ -151,7 +155,11 @@ class DynamicDownloadDialogBehavior<V : View>(
addUpdateListener { child.translationY = it.animatedValue as Float } addUpdateListener { child.translationY = it.animatedValue as Float }
setFloatValues( setFloatValues(
child.translationY, child.translationY,
if (direction == SnapDirection.UP) 0f else child.height.toFloat() + bottomToolbarHeight if (direction == SnapDirection.UP) {
0f
} else {
child.height.toFloat() + bottomToolbarHeight
}
) )
start() start()
} }

@ -49,7 +49,6 @@ import org.mozilla.fenix.compose.TabSubtitleWithInterdot
import org.mozilla.fenix.compose.TabTitle import org.mozilla.fenix.compose.TabTitle
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.random.Random
private const val URI_PARAM_UTM_KEY = "utm_source" private const val URI_PARAM_UTM_KEY = "utm_source"
private const val POCKET_STORIES_UTM_VALUE = "pocket-newtab-android" private const val POCKET_STORIES_UTM_VALUE = "pocket-newtab-android"
@ -274,17 +273,15 @@ private class PocketStoryProvider : PreviewParameterProvider<PocketRecommendedSt
internal fun getFakePocketStories(limit: Int = 1): List<PocketRecommendedStory> { internal fun getFakePocketStories(limit: Int = 1): List<PocketRecommendedStory> {
return mutableListOf<PocketRecommendedStory>().apply { return mutableListOf<PocketRecommendedStory>().apply {
for (index in 0 until limit) { for (index in 0 until limit) {
val randomNumber = Random.nextInt(0, 10)
add( add(
PocketRecommendedStory( PocketRecommendedStory(
title = "This is a ${"very ".repeat(randomNumber)} long title", title = "This is a ${"very ".repeat(index)} long title",
publisher = "Publisher", publisher = "Publisher",
url = "https://story$randomNumber.com", url = "https://story$index.com",
imageUrl = "", imageUrl = "",
timeToRead = randomNumber, timeToRead = index,
category = "Category #$randomNumber", category = "Category #$index",
timesShown = randomNumber.toLong() timesShown = index.toLong()
) )
) )
} }

@ -651,8 +651,11 @@ class DefaultSessionControlController(
override fun handleReportSessionMetrics(state: AppState) { override fun handleReportSessionMetrics(state: AppState) {
with(metrics) { with(metrics) {
track( track(
if (state.recentTabs.isEmpty()) Event.RecentTabsSectionIsNotVisible if (state.recentTabs.isEmpty()) {
else Event.RecentTabsSectionIsVisible Event.RecentTabsSectionIsNotVisible
} else {
Event.RecentTabsSectionIsVisible
}
) )
track(Event.RecentBookmarkCount(state.recentBookmarks.size)) track(Event.RecentBookmarkCount(state.recentBookmarks.size))

@ -77,8 +77,11 @@ class TopSitesPagerAdapter(
@VisibleForTesting @VisibleForTesting
internal fun getCurrentPageChanges(payload: TopSitePagerPayload, position: Int) = internal fun getCurrentPageChanges(payload: TopSitePagerPayload, position: Int) =
payload.changed.filter { changedPair -> payload.changed.filter { changedPair ->
if (position == 0) changedPair.first < TOP_SITES_PER_PAGE if (position == 0) {
else changedPair.first >= TOP_SITES_PER_PAGE changedPair.first < TOP_SITES_PER_PAGE
} else {
changedPair.first >= TOP_SITES_PER_PAGE
}
} }
override fun onBindViewHolder(holder: TopSiteViewHolder, position: Int) { override fun onBindViewHolder(holder: TopSiteViewHolder, position: Int) {

@ -104,8 +104,11 @@ class HistoryView(
val numRecentTabs = recentlyClosedNav.context.components.core.store.state.closedTabs.size val numRecentTabs = recentlyClosedNav.context.components.core.store.state.closedTabs.size
recentlyClosedTabsDescription.text = String.format( recentlyClosedTabsDescription.text = String.format(
context.getString( context.getString(
if (numRecentTabs == 1) if (numRecentTabs == 1) {
R.string.recently_closed_tab else R.string.recently_closed_tabs R.string.recently_closed_tab
} else {
R.string.recently_closed_tabs
}
), ),
numRecentTabs numRecentTabs
) )

@ -116,8 +116,11 @@ class HistoryListItemViewHolder(
val numRecentTabs = itemView.context.components.core.store.state.closedTabs.size val numRecentTabs = itemView.context.components.core.store.state.closedTabs.size
binding.recentlyClosedNavEmpty.recentlyClosedTabsDescription.text = String.format( binding.recentlyClosedNavEmpty.recentlyClosedTabsDescription.text = String.format(
itemView.context.getString( itemView.context.getString(
if (numRecentTabs == 1) if (numRecentTabs == 1) {
R.string.recently_closed_tab else R.string.recently_closed_tabs R.string.recently_closed_tab
} else {
R.string.recently_closed_tabs
}
), ),
numRecentTabs numRecentTabs
) )

@ -72,9 +72,11 @@ class PairFragment : Fragment(R.layout.fragment_pair), UserInteractionHandler {
scanMessage = scanMessage =
if (requireContext().settings().allowDomesticChinaFxaServer && if (requireContext().settings().allowDomesticChinaFxaServer &&
org.mozilla.fenix.Config.channel.isMozillaOnline org.mozilla.fenix.Config.channel.isMozillaOnline
) ) {
R.string.pair_instructions_2_cn R.string.pair_instructions_2_cn
else R.string.pair_instructions_2 } else {
R.string.pair_instructions_2
}
), ),
owner = this, owner = this,
view = view view = view

@ -107,11 +107,11 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
accountSettingsStore = StoreProvider.get(this) { accountSettingsStore = StoreProvider.get(this) {
AccountSettingsFragmentStore( AccountSettingsFragmentStore(
AccountSettingsFragmentState( AccountSettingsFragmentState(
lastSyncedDate = lastSyncedDate = if (getLastSynced(requireContext()) == 0L) {
if (getLastSynced(requireContext()) == 0L)
LastSyncTime.Never LastSyncTime.Never
else } else {
LastSyncTime.Success(getLastSynced(requireContext())), LastSyncTime.Success(getLastSynced(requireContext()))
},
deviceName = requireComponents.backgroundServices.defaultDeviceName( deviceName = requireComponents.backgroundServices.defaultDeviceName(
requireContext() requireContext()
) )

@ -91,10 +91,10 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (pairWithEmailStarted || if (pairWithEmailStarted ||
requireComponents.backgroundServices.accountManager.authenticatedAccount() != null requireComponents.backgroundServices.accountManager.authenticatedAccount() != null
) { ) {
findNavController().popBackStack() findNavController().popBackStack()
return return
} }
@ -118,9 +118,11 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
binding.signInScanButton.setOnClickListener(paringClickListener) binding.signInScanButton.setOnClickListener(paringClickListener)
binding.signInEmailButton.setOnClickListener(signInClickListener) binding.signInEmailButton.setOnClickListener(signInClickListener)
binding.signInInstructions.text = HtmlCompat.fromHtml( binding.signInInstructions.text = HtmlCompat.fromHtml(
if (requireContext().settings().allowDomesticChinaFxaServer && Config.channel.isMozillaOnline) if (requireContext().settings().allowDomesticChinaFxaServer && Config.channel.isMozillaOnline) {
getString(R.string.sign_in_instructions_cn) getString(R.string.sign_in_instructions_cn)
else getString(R.string.sign_in_instructions), } else {
getString(R.string.sign_in_instructions)
},
HtmlCompat.FROM_HTML_MODE_LEGACY HtmlCompat.FROM_HTML_MODE_LEGACY
) )

@ -192,12 +192,14 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da
.setText(resources.getString(R.string.preferences_delete_browsing_data_snackbar)) .setText(resources.getString(R.string.preferences_delete_browsing_data_snackbar))
.show() .show()
if (popAfter) viewLifecycleOwner.lifecycleScope.launch(Main) { if (popAfter) {
findNavController().apply { viewLifecycleOwner.lifecycleScope.launch(Main) {
// If the user deletes all open tabs we need to make sure we remove findNavController().apply {
// the BrowserFragment from the backstack. // If the user deletes all open tabs we need to make sure we remove
popBackStack(R.id.homeFragment, false) // the BrowserFragment from the backstack.
navigate(DeleteBrowsingDataFragmentDirections.actionGlobalSettingsFragment()) popBackStack(R.id.homeFragment, false)
navigate(DeleteBrowsingDataFragmentDirections.actionGlobalSettingsFragment())
}
} }
} }
} }

@ -39,8 +39,6 @@ open class SavedLoginsStorageController(
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) { ) {
private suspend fun getLogin(loginId: String): Login? = passwordsStorage.get(loginId)
fun delete(loginId: String) { fun delete(loginId: String) {
var deleteLoginJob: Deferred<Boolean>? = null var deleteLoginJob: Deferred<Boolean>? = null
val deleteJob = lifecycleScope.launch(ioDispatcher) { val deleteJob = lifecycleScope.launch(ioDispatcher) {

@ -89,9 +89,11 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
requirePreference<Preference>(R.string.pref_key_save_logins_settings).apply { requirePreference<Preference>(R.string.pref_key_save_logins_settings).apply {
summary = getString( summary = getString(
if (context.settings().shouldPromptToSaveLogins) if (context.settings().shouldPromptToSaveLogins) {
R.string.preferences_passwords_save_logins_ask_to_save else R.string.preferences_passwords_save_logins_ask_to_save
} else {
R.string.preferences_passwords_save_logins_never_save R.string.preferences_passwords_save_logins_never_save
}
) )
setOnPreferenceClickListener { setOnPreferenceClickListener {
navigateToSaveLoginSettingFragment() navigateToSaveLoginSettingFragment()

@ -14,7 +14,6 @@ import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.permission.SitePermissions import mozilla.components.concept.engine.permission.SitePermissions
import mozilla.components.feature.session.SessionUseCases.ReloadUrlUseCase import mozilla.components.feature.session.SessionUseCases.ReloadUrlUseCase
import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
import mozilla.components.support.base.feature.OnNeedToRequestPermissions import mozilla.components.support.base.feature.OnNeedToRequestPermissions
import mozilla.components.support.ktx.kotlin.getOrigin import mozilla.components.support.ktx.kotlin.getOrigin
import mozilla.telemetry.glean.private.NoExtras import mozilla.telemetry.glean.private.NoExtras
@ -95,11 +94,9 @@ interface QuickSettingsController {
* @param settings [Settings] application settings. * @param settings [Settings] application settings.
* @param permissionStorage [PermissionStorage] app state for website permissions exception. * @param permissionStorage [PermissionStorage] app state for website permissions exception.
* @param reload [ReloadUrlUseCase] callback allowing for reloading the current web page. * @param reload [ReloadUrlUseCase] callback allowing for reloading the current web page.
* @param addNewTab [AddNewTabUseCase] callback allowing for loading a URL in a new tab.
* @param requestRuntimePermissions [OnNeedToRequestPermissions] callback allowing for requesting * @param requestRuntimePermissions [OnNeedToRequestPermissions] callback allowing for requesting
* specific Android runtime permissions. * specific Android runtime permissions.
* @param displayPermissions callback for when [WebsitePermissionsView] needs to be displayed. * @param displayPermissions callback for when [WebsitePermissionsView] needs to be displayed.
* @param dismiss callback allowing to request this entire Fragment to be dismissed.
*/ */
@Suppress("TooManyFunctions") @Suppress("TooManyFunctions")
class DefaultQuickSettingsController( class DefaultQuickSettingsController(
@ -115,11 +112,9 @@ class DefaultQuickSettingsController(
private val settings: Settings, private val settings: Settings,
private val permissionStorage: PermissionStorage, private val permissionStorage: PermissionStorage,
private val reload: ReloadUrlUseCase, private val reload: ReloadUrlUseCase,
private val addNewTab: AddNewTabUseCase,
private val requestRuntimePermissions: OnNeedToRequestPermissions = { }, private val requestRuntimePermissions: OnNeedToRequestPermissions = { },
private val displayPermissions: () -> Unit, private val displayPermissions: () -> Unit,
private val engine: Engine = context.components.core.engine, private val engine: Engine = context.components.core.engine,
private val dismiss: () -> Unit
) : QuickSettingsController { ) : QuickSettingsController {
override fun handlePermissionsShown() { override fun handlePermissionsShown() {
displayPermissions() displayPermissions()

@ -103,13 +103,11 @@ class QuickSettingsSheetDialogFragment : FenixDialogFragment() {
settings = components.settings, settings = components.settings,
permissionStorage = components.core.permissionStorage, permissionStorage = components.core.permissionStorage,
reload = components.useCases.sessionUseCases.reload, reload = components.useCases.sessionUseCases.reload,
addNewTab = components.useCases.tabsUseCases.addTab,
requestRuntimePermissions = { permissions -> requestRuntimePermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_QUICK_SETTINGS_PERMISSIONS) requestPermissions(permissions, REQUEST_CODE_QUICK_SETTINGS_PERMISSIONS)
tryToRequestPermissions = true tryToRequestPermissions = true
}, },
displayPermissions = ::showPermissionsView, displayPermissions = ::showPermissionsView
dismiss = ::dismiss
) )
interactor = QuickSettingsInteractor(quickSettingsController) interactor = QuickSettingsInteractor(quickSettingsController)

@ -14,14 +14,6 @@ import org.mozilla.fenix.home.intent.StartSearchIntentProcessor
class NewTabShortcutIntentProcessor : IntentProcessor { class NewTabShortcutIntentProcessor : IntentProcessor {
/**
* Returns true if this intent processor will handle the intent.
*/
private fun matches(intent: Intent): Boolean {
val safeIntent = SafeIntent(intent)
return safeIntent.action == ACTION_OPEN_TAB || safeIntent.action == ACTION_OPEN_PRIVATE_TAB
}
/** /**
* Processes the given [Intent]. * Processes the given [Intent].
* *

@ -322,7 +322,6 @@ class TabsTrayFragment : AppCompatDialogFragment() {
store = tabsTrayStore, store = tabsTrayStore,
navInteractor = navigationInteractor, navInteractor = navigationInteractor,
tabsTrayInteractor = tabsTrayInteractor, tabsTrayInteractor = tabsTrayInteractor,
containerView = view,
backgroundView = tabsTrayBinding.topBar, backgroundView = tabsTrayBinding.topBar,
showOnSelectViews = VisibilityModifier( showOnSelectViews = VisibilityModifier(
tabsTrayMultiselectItemsBinding.collectMultiSelect, tabsTrayMultiselectItemsBinding.collectMultiSelect,

@ -34,8 +34,6 @@ import org.mozilla.fenix.tabstray.ext.showWithTheme
* @property store The TabsTrayStore instance. * @property store The TabsTrayStore instance.
* @property navInteractor An instance of [NavigationInteractor] for navigating on menu clicks. * @property navInteractor An instance of [NavigationInteractor] for navigating on menu clicks.
* @property tabsTrayInteractor An instance of [TabsTrayInteractor] for handling deletion. * @property tabsTrayInteractor An instance of [TabsTrayInteractor] for handling deletion.
* @property containerView The view in the layout that contains all the implicit multi-select
* views. NB: This parameter is a bit opaque and requires a larger layout refactor to correct.
* @property backgroundView The background view that we want to alter when changing [Mode]. * @property backgroundView The background view that we want to alter when changing [Mode].
* @property showOnSelectViews A variable list of views that will be made visible when in select mode. * @property showOnSelectViews A variable list of views that will be made visible when in select mode.
* @property showOnNormalViews A variable list of views that will be made visible when in normal mode. * @property showOnNormalViews A variable list of views that will be made visible when in normal mode.
@ -48,7 +46,6 @@ class SelectionBannerBinding(
private val store: TabsTrayStore, private val store: TabsTrayStore,
private val navInteractor: NavigationInteractor, private val navInteractor: NavigationInteractor,
private val tabsTrayInteractor: TabsTrayInteractor, private val tabsTrayInteractor: TabsTrayInteractor,
private val containerView: View,
private val backgroundView: View, private val backgroundView: View,
private val showOnSelectViews: VisibilityModifier, private val showOnSelectViews: VisibilityModifier,
private val showOnNormalViews: VisibilityModifier private val showOnNormalViews: VisibilityModifier

@ -70,7 +70,6 @@ class Settings(private val appContext: Context) : PreferencesHolder {
private const val ALLOWED_INT = 2 private const val ALLOWED_INT = 2
private const val CFR_COUNT_CONDITION_FOCUS_INSTALLED = 1 private const val CFR_COUNT_CONDITION_FOCUS_INSTALLED = 1
private const val CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED = 3 private const val CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED = 3
private const val APP_LAUNCHES_TO_SHOW_DEFAULT_BROWSER_CARD = 3
private const val INACTIVE_TAB_MINIMUM_TO_SHOW_AUTO_CLOSE_DIALOG = 20 private const val INACTIVE_TAB_MINIMUM_TO_SHOW_AUTO_CLOSE_DIALOG = 20
const val FOUR_HOURS_MS = 60 * 60 * 4 * 1000L const val FOUR_HOURS_MS = 60 * 60 * 4 * 1000L

@ -224,8 +224,11 @@ class SearchWidgetProvider : AppWidgetProvider() {
SearchWidgetProviderSize.LARGE -> R.layout.search_widget_large SearchWidgetProviderSize.LARGE -> R.layout.search_widget_large
SearchWidgetProviderSize.MEDIUM -> R.layout.search_widget_medium SearchWidgetProviderSize.MEDIUM -> R.layout.search_widget_medium
SearchWidgetProviderSize.SMALL -> { SearchWidgetProviderSize.SMALL -> {
if (showMic) R.layout.search_widget_small if (showMic) {
else R.layout.search_widget_small_no_mic R.layout.search_widget_small
} else {
R.layout.search_widget_small_no_mic
}
} }
SearchWidgetProviderSize.EXTRA_SMALL_V2 -> R.layout.search_widget_extra_small_v2 SearchWidgetProviderSize.EXTRA_SMALL_V2 -> R.layout.search_widget_extra_small_v2
SearchWidgetProviderSize.EXTRA_SMALL_V1 -> R.layout.search_widget_extra_small_v1 SearchWidgetProviderSize.EXTRA_SMALL_V1 -> R.layout.search_widget_extra_small_v1

@ -19,7 +19,6 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.perf.StrictModeManager import org.mozilla.fenix.perf.StrictModeManager
import org.mozilla.fenix.helpers.perf.TestStrictModeManager import org.mozilla.fenix.helpers.perf.TestStrictModeManager
import kotlin.coroutines.CoroutineContext
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
class AccountAbnormalitiesTest { class AccountAbnormalitiesTest {
@ -28,7 +27,11 @@ class AccountAbnormalitiesTest {
val crashReporter: CrashReporter = mockk() val crashReporter: CrashReporter = mockk()
// no account present // no account present
val accountAbnormalities = newAccountAbnormalities(crashReporter) val accountAbnormalities = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
try { try {
accountAbnormalities.userRequestedLogout() accountAbnormalities.userRequestedLogout()
@ -54,7 +57,11 @@ class AccountAbnormalitiesTest {
fun `LogoutWithoutAuth detected`() = runBlocking { fun `LogoutWithoutAuth detected`() = runBlocking {
val crashReporter: CrashReporter = mockk(relaxed = true) val crashReporter: CrashReporter = mockk(relaxed = true)
val accountAbnormalities = newAccountAbnormalities(crashReporter, this.coroutineContext) val accountAbnormalities = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
accountAbnormalities.onReady(mockk(relaxed = true)) accountAbnormalities.onReady(mockk(relaxed = true))
// Logout action must be preceded by auth. // Logout action must be preceded by auth.
@ -66,7 +73,11 @@ class AccountAbnormalitiesTest {
fun `OverlappingFxaLogoutRequest detected`() = runBlocking { fun `OverlappingFxaLogoutRequest detected`() = runBlocking {
val crashReporter: CrashReporter = mockk(relaxed = true) val crashReporter: CrashReporter = mockk(relaxed = true)
val accountAbnormalities = newAccountAbnormalities(crashReporter, this.coroutineContext) val accountAbnormalities = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
accountAbnormalities.onReady(mockk(relaxed = true)) accountAbnormalities.onReady(mockk(relaxed = true))
accountAbnormalities.onAuthenticated(mockk(), mockk()) accountAbnormalities.onAuthenticated(mockk(), mockk())
@ -83,7 +94,11 @@ class AccountAbnormalitiesTest {
fun `callback logout abnormalities detected`() = runBlocking { fun `callback logout abnormalities detected`() = runBlocking {
val crashReporter: CrashReporter = mockk(relaxed = true) val crashReporter: CrashReporter = mockk(relaxed = true)
val accountAbnormalities = newAccountAbnormalities(crashReporter, this.coroutineContext) val accountAbnormalities = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
accountAbnormalities.onReady(mockk(relaxed = true)) accountAbnormalities.onReady(mockk(relaxed = true))
// User didn't request this logout. // User didn't request this logout.
@ -96,7 +111,11 @@ class AccountAbnormalitiesTest {
val crashReporter: CrashReporter = mockk(relaxed = true) val crashReporter: CrashReporter = mockk(relaxed = true)
val accountManager: FxaAccountManager = mockk(relaxed = true) val accountManager: FxaAccountManager = mockk(relaxed = true)
val accountAbnormalities = newAccountAbnormalities(crashReporter, this.coroutineContext) val accountAbnormalities = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
accountAbnormalities.onReady(null) accountAbnormalities.onReady(null)
accountAbnormalities.onAuthenticated(mockk(), mockk()) accountAbnormalities.onAuthenticated(mockk(), mockk())
@ -104,7 +123,11 @@ class AccountAbnormalitiesTest {
every { accountManager.authenticatedAccount() } returns null every { accountManager.authenticatedAccount() } returns null
// Pretend we restart, and instantiate a new middleware instance. // Pretend we restart, and instantiate a new middleware instance.
val accountAbnormalities2 = newAccountAbnormalities(crashReporter, this.coroutineContext) val accountAbnormalities2 = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
// mock accountManager doesn't have an account, but we expect it to have one since we // mock accountManager doesn't have an account, but we expect it to have one since we
// were authenticated before our "restart". // were authenticated before our "restart".
accountAbnormalities2.onReady(null) accountAbnormalities2.onReady(null)
@ -116,7 +139,11 @@ class AccountAbnormalitiesTest {
fun `logout happy case`() = runBlocking { fun `logout happy case`() = runBlocking {
val crashReporter: CrashReporter = mockk() val crashReporter: CrashReporter = mockk()
val accountAbnormalities = newAccountAbnormalities(crashReporter, coroutineContext) val accountAbnormalities = AccountAbnormalities(
testContext,
crashReporter,
TestStrictModeManager() as StrictModeManager
)
accountAbnormalities.onReady(mockk(relaxed = true)) accountAbnormalities.onReady(mockk(relaxed = true))
// We saw an auth event, then user requested a logout. // We saw an auth event, then user requested a logout.
@ -130,13 +157,4 @@ class AccountAbnormalitiesTest {
crashReporter.submitCaughtException(any<T>()) crashReporter.submitCaughtException(any<T>())
} }
} }
private fun newAccountAbnormalities(
crashReporter: CrashReporter,
coroutineContext: CoroutineContext? = null
): AccountAbnormalities = if (coroutineContext != null) {
AccountAbnormalities(testContext, crashReporter, TestStrictModeManager() as StrictModeManager, coroutineContext)
} else {
AccountAbnormalities(testContext, crashReporter, TestStrictModeManager() as StrictModeManager)
}
} }

@ -26,7 +26,6 @@ import mozilla.components.concept.engine.permission.SitePermissions
import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION
import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.TrackingProtectionUseCases import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.service.glean.testing.GleanTestRule import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.mock import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.robolectric.testContext
@ -81,9 +80,6 @@ class DefaultQuickSettingsControllerTest {
@MockK(relaxed = true) @MockK(relaxed = true)
private lateinit var reload: SessionUseCases.ReloadUrlUseCase private lateinit var reload: SessionUseCases.ReloadUrlUseCase
@MockK(relaxed = true)
private lateinit var addNewTab: TabsUseCases.AddNewTabUseCase
@MockK(relaxed = true) @MockK(relaxed = true)
private lateinit var requestPermissions: (Array<String>) -> Unit private lateinit var requestPermissions: (Array<String>) -> Unit
@ -112,11 +108,9 @@ class DefaultQuickSettingsControllerTest {
settings = appSettings, settings = appSettings,
permissionStorage = permissionStorage, permissionStorage = permissionStorage,
reload = reload, reload = reload,
addNewTab = addNewTab,
requestRuntimePermissions = requestPermissions, requestRuntimePermissions = requestPermissions,
engine = engine, engine = engine,
displayPermissions = {}, displayPermissions = {}
dismiss = {}
) )
) )
} }
@ -192,10 +186,8 @@ class DefaultQuickSettingsControllerTest {
settings = appSettings, settings = appSettings,
permissionStorage = permissionStorage, permissionStorage = permissionStorage,
reload = reload, reload = reload,
addNewTab = addNewTab,
requestRuntimePermissions = requestPermissions, requestRuntimePermissions = requestPermissions,
displayPermissions = {}, displayPermissions = {}
dismiss = {}
) )
every { websitePermission.phoneFeature } returns PhoneFeature.CAMERA every { websitePermission.phoneFeature } returns PhoneFeature.CAMERA
@ -416,8 +408,7 @@ class DefaultQuickSettingsControllerTest {
private fun createController( private fun createController(
requestPermissions: (Array<String>) -> Unit = { _ -> }, requestPermissions: (Array<String>) -> Unit = { _ -> },
displayPermissions: () -> Unit = { }, displayPermissions: () -> Unit = {}
dismiss: () -> Unit = { }
): DefaultQuickSettingsController { ): DefaultQuickSettingsController {
return spyk( return spyk(
DefaultQuickSettingsController( DefaultQuickSettingsController(
@ -431,10 +422,8 @@ class DefaultQuickSettingsControllerTest {
settings = appSettings, settings = appSettings,
permissionStorage = permissionStorage, permissionStorage = permissionStorage,
reload = reload, reload = reload,
addNewTab = addNewTab,
requestRuntimePermissions = requestPermissions, requestRuntimePermissions = requestPermissions,
displayPermissions = displayPermissions, displayPermissions = displayPermissions
dismiss = dismiss
) )
) )
} }

@ -78,7 +78,7 @@ buildscript {
} }
plugins { plugins {
id("io.gitlab.arturbosch.detekt").version("1.17.1") id("io.gitlab.arturbosch.detekt").version("1.19.0")
} }
allprojects { allprojects {
@ -154,8 +154,6 @@ tasks.register('clean', Delete) {
} }
detekt { detekt {
// The version number is duplicated, please refer to plugins block for more details
version = "1.17.1"
input = files("$projectDir/app/src") input = files("$projectDir/app/src")
config = files("$projectDir/config/detekt.yml") config = files("$projectDir/config/detekt.yml")
@ -167,9 +165,31 @@ detekt {
xml { xml {
enabled = false enabled = false
} }
txt {
enabled = false
}
} }
} }
tasks.withType(io.gitlab.arturbosch.detekt.Detekt).configureEach() {
autoCorrect = true
exclude "**/test/**"
exclude "**/androidTest/**"
exclude "**/build/**"
exclude "**/resources/**"
exclude "**/tmp/**"
}
// Apply same path exclusions as for the main task
tasks.withType(io.gitlab.arturbosch.detekt.DetektCreateBaselineTask).configureEach() {
exclude "**/test/**"
exclude "**/androidTest/**"
exclude "**/build/**"
exclude "**/resources/**"
exclude "**/tmp/**"
}
configurations { configurations {
ktlint ktlint
} }

@ -17,7 +17,7 @@ object Versions {
const val sentry = "5.6.2" const val sentry = "5.6.2"
const val leakcanary = "2.8.1" const val leakcanary = "2.8.1"
const val osslicenses_plugin = "0.10.4" const val osslicenses_plugin = "0.10.4"
const val detekt = "1.17.1" const val detekt = "1.19.0"
const val jna = "5.6.0" const val jna = "5.6.0"
const val androidx_activity_compose = "1.4.0" const val androidx_activity_compose = "1.4.0"

@ -1,5 +1,6 @@
build: build:
maxIssues: 0 maxIssues: 0
excludeCorrectable: false
weights: weights:
# complexity: 2 # complexity: 2
# LongParameterList: 1 # LongParameterList: 1
@ -9,11 +10,19 @@ build:
processors: processors:
active: true active: true
exclude: exclude:
# - 'DetektProgressListener'
# - 'KtFileCountProcessor'
# - 'PackageCountProcessor'
# - 'ClassCountProcessor'
# - 'FunctionCountProcessor' # - 'FunctionCountProcessor'
# - 'PropertyCountProcessor' # - 'PropertyCountProcessor'
# - 'ClassCountProcessor' # - 'ProjectComplexityProcessor'
# - 'PackageCountProcessor' # - 'ProjectCognitiveComplexityProcessor'
# - 'KtFileCountProcessor' # - 'ProjectLLOCProcessor'
# - 'ProjectCLOCProcessor'
# - 'ProjectLOCProcessor'
# - 'ProjectSLOCProcessor'
# - 'LicenseHeaderLoaderExtension'
console-reports: console-reports:
active: true active: true
@ -22,30 +31,37 @@ console-reports:
# - 'ComplexityReport' # - 'ComplexityReport'
# - 'NotificationReport' # - 'NotificationReport'
# - 'FindingsReport' # - 'FindingsReport'
# - 'BuildFailureReport' # - 'FileBasedFindingsReport'
# - 'HtmlOutputReport' - 'LiteFindingsReport'
- 'PlainOutputReport'
- 'XmlOutputReport'
comments: comments:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
AbsentOrWrongFileLicense: AbsentOrWrongFileLicense:
active: true active: false
licenseTemplateFile: 'license.template'
licenseTemplateIsRegex: false
CommentOverPrivateFunction: CommentOverPrivateFunction:
active: false active: false
CommentOverPrivateProperty: CommentOverPrivateProperty:
active: false active: false
DeprecatedBlockTag:
active: false
EndOfSentenceFormat: EndOfSentenceFormat:
active: false active: false
endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!]$) endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
UndocumentedPublicClass: OutdatedDocumentation:
active: false active: false
matchTypeParameters: true
matchDeclarationsOrder: true
UndocumentedPublicClass:
active: true
searchInNestedClass: true searchInNestedClass: true
searchInInnerClass: true searchInInnerClass: true
searchInInnerObject: true searchInInnerObject: true
searchInInnerInterface: true searchInInnerInterface: true
UndocumentedPublicFunction: UndocumentedPublicFunction:
active: true
UndocumentedPublicProperty:
active: false active: false
complexity: complexity:
@ -57,52 +73,83 @@ complexity:
active: false active: false
threshold: 10 threshold: 10
includeStaticDeclarations: false includeStaticDeclarations: false
includePrivateDeclarations: false
ComplexMethod: ComplexMethod:
active: true active: true
threshold: 15 threshold: 18
ignoreSingleWhenExpression: true ignoreSingleWhenExpression: true
ignoreSimpleWhenEntries: false
ignoreNestingFunctions: false
nestingFunctions:
- 'also'
- 'apply'
- 'forEach'
- 'isNotNull'
- 'ifNull'
- 'let'
- 'run'
- 'use'
- 'with'
LabeledExpression: LabeledExpression:
active: false active: false
ignoredLabels: []
LargeClass: LargeClass:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" threshold: 600
# Had to increase the threshold as RC13 started counting lines of code
# https://github.com/mozilla-mobile/fenix/issues/4861
threshold: 200
LongMethod: LongMethod:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
# Had to increase the threshold as RC13 started counting lines of code
# https://github.com/mozilla-mobile/fenix/issues/4861
threshold: 75 threshold: 75
LongParameterList: LongParameterList:
active: true active: true
excludes: "**/*Controller.kt, **/*Integration.kt"
functionThreshold: 6 functionThreshold: 6
constructorThreshold: 7 constructorThreshold: 7
ignoreDefaultParameters: false ignoreDefaultParameters: true
ignoreDataClasses: true ignoreDataClasses: true
ignoreAnnotatedParameter: []
MethodOverloading: MethodOverloading:
active: false active: false
threshold: 6 threshold: 6
NamedArguments:
active: false
threshold: 3
NestedBlockDepth: NestedBlockDepth:
active: true active: true
threshold: 4 threshold: 4
ReplaceSafeCallChainWithRun:
active: false
StringLiteralDuplication: StringLiteralDuplication:
active: false active: false
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
threshold: 3 threshold: 3
ignoreAnnotation: true ignoreAnnotation: true
excludeStringsWithLessThan5Characters: true excludeStringsWithLessThan5Characters: true
ignoreStringsRegex: '$^' ignoreStringsRegex: '$^'
TooManyFunctions: TooManyFunctions:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" thresholdInFiles: 26
thresholdInFiles: 11 thresholdInClasses: 26
thresholdInClasses: 11 thresholdInInterfaces: 26
thresholdInInterfaces: 11 thresholdInObjects: 26
thresholdInObjects: 11
thresholdInEnums: 11 thresholdInEnums: 11
ignoreDeprecated: false
ignorePrivate: false
ignoreOverridden: false
coroutines:
active: true
GlobalCoroutineUsage:
active: false
InjectDispatcher:
active: false
dispatcherNames:
- 'IO'
- 'Default'
- 'Unconfined'
RedundantSuspendModifier:
active: false
SleepInsteadOfDelay:
active: false
SuspendFunWithFlowReturnType:
active: false
mozilla-detekt-rules: mozilla-detekt-rules:
active: true active: true
@ -111,15 +158,13 @@ mozilla-detekt-rules:
# BuildConfig.Debug: This property tests whether the application was built # BuildConfig.Debug: This property tests whether the application was built
# with the debuggable flag or not. Use a check for different build variants, # with the debuggable flag or not. Use a check for different build variants,
# instead. # instead.
bannedProperties: "BuildConfig.DEBUG" bannedProperties: 'BuildConfig.DEBUG'
MozillaStrictModeSuppression: MozillaStrictModeSuppression:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
MozillaCorrectUnitTestRunner: MozillaCorrectUnitTestRunner:
active: true active: true
MozillaRunBlockingCheck: MozillaRunBlockingCheck:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
MozillaUseLazyMonitored: MozillaUseLazyMonitored:
active: true active: true
@ -127,7 +172,7 @@ empty-blocks:
active: true active: true
EmptyCatchBlock: EmptyCatchBlock:
active: true active: true
allowedExceptionNameRegex: "^(ignore|expected).*" allowedExceptionNameRegex: '_|(ignore|expected).*'
EmptyClassBlock: EmptyClassBlock:
active: true active: true
EmptyDefaultConstructor: EmptyDefaultConstructor:
@ -142,7 +187,7 @@ empty-blocks:
active: true active: true
EmptyFunctionBlock: EmptyFunctionBlock:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" ignoreOverridden: false
EmptyIfBlock: EmptyIfBlock:
active: true active: true
EmptyInitBlock: EmptyInitBlock:
@ -151,6 +196,8 @@ empty-blocks:
active: true active: true
EmptySecondaryConstructor: EmptySecondaryConstructor:
active: true active: true
EmptyTryBlock:
active: true
EmptyWhenBlock: EmptyWhenBlock:
active: true active: true
EmptyWhileBlock: EmptyWhileBlock:
@ -160,61 +207,90 @@ exceptions:
active: true active: true
ExceptionRaisedInUnexpectedLocation: ExceptionRaisedInUnexpectedLocation:
active: false active: false
methodNames: 'toString,hashCode,equals,finalize' methodNames:
- 'equals'
- 'finalize'
- 'hashCode'
- 'toString'
InstanceOfCheckForException: InstanceOfCheckForException:
active: false active: false
NotImplementedDeclaration: NotImplementedDeclaration:
active: false active: false
PrintStackTrace: ObjectExtendsThrowable:
active: false active: false
PrintStackTrace:
active: true
RethrowCaughtException: RethrowCaughtException:
active: false active: false
ReturnFromFinally: ReturnFromFinally:
active: false active: true
ignoreLabeled: false
SwallowedException: SwallowedException:
active: false active: false
ignoredExceptionTypes:
- 'InterruptedException'
- 'MalformedURLException'
- 'NumberFormatException'
- 'ParseException'
allowedExceptionNameRegex: '_|(ignore|expected).*'
ThrowingExceptionFromFinally: ThrowingExceptionFromFinally:
active: false active: true
ThrowingExceptionInMain: ThrowingExceptionInMain:
active: false active: false
ThrowingExceptionsWithoutMessageOrCause: ThrowingExceptionsWithoutMessageOrCause:
active: false active: false
exceptions: 'IllegalArgumentException,IllegalStateException,IOException' exceptions:
- 'ArrayIndexOutOfBoundsException'
- 'Exception'
- 'IllegalArgumentException'
- 'IllegalMonitorStateException'
- 'IllegalStateException'
- 'IndexOutOfBoundsException'
- 'NullPointerException'
- 'RuntimeException'
- 'Throwable'
ThrowingNewInstanceOfSameException: ThrowingNewInstanceOfSameException:
active: false active: true
TooGenericExceptionCaught: TooGenericExceptionCaught:
active: true active: true
exceptionNames: exceptionNames:
- ArrayIndexOutOfBoundsException - 'ArrayIndexOutOfBoundsException'
- Error - 'Error'
- Exception - 'Exception'
- IllegalMonitorStateException - 'IllegalMonitorStateException'
- NullPointerException - 'IndexOutOfBoundsException'
- IndexOutOfBoundsException - 'NullPointerException'
- RuntimeException - 'RuntimeException'
- Throwable - 'Throwable'
allowedExceptionNameRegex: '_|(ignore|expected).*'
TooGenericExceptionThrown: TooGenericExceptionThrown:
active: true active: true
exceptionNames: exceptionNames:
- Error - 'Error'
- Exception - 'Exception'
- Throwable - 'RuntimeException'
- RuntimeException - 'Throwable'
formatting:
autoCorrect: true
naming: naming:
active: true active: true
BooleanPropertyNaming:
active: false
allowedPattern: '^(is|has|are)'
ClassNaming: ClassNaming:
active: true active: true
classPattern: '[A-Z$][a-zA-Z0-9$]*' classPattern: '[A-Z][a-zA-Z0-9]*'
ConstructorParameterNaming:
active: true
parameterPattern: '[a-z][A-Za-z0-9]*'
privateParameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverridden: true
EnumNaming: EnumNaming:
active: true active: true
enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*' enumEntryPattern: '[A-Z][_a-zA-Z0-9]*'
ForbiddenClassName: ForbiddenClassName:
active: false active: false
forbiddenName: '' forbiddenName: []
FunctionMaxLength: FunctionMaxLength:
active: false active: false
maximumFunctionNameLength: 30 maximumFunctionNameLength: 30
@ -223,25 +299,44 @@ naming:
minimumFunctionNameLength: 3 minimumFunctionNameLength: 3
FunctionNaming: FunctionNaming:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)'
functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' excludeClassPattern: '$^'
ignoreOverridden: true
ignoreAnnotated: ['Composable']
FunctionParameterNaming:
active: true
parameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^' excludeClassPattern: '$^'
ignoreOverridden: true
InvalidPackageDeclaration:
active: false
rootPackage: ''
LambdaParameterNaming:
active: false
parameterPattern: '[a-z][A-Za-z0-9]*|_'
MatchingDeclarationName: MatchingDeclarationName:
active: true active: true
mustBeFirst: true
MemberNameEqualsClassName: MemberNameEqualsClassName:
active: false active: false
ignoreOverridden: true ignoreOverridden: true
NoNameShadowing:
active: false
NonBooleanPropertyPrefixedWithIs:
active: false
ObjectPropertyNaming: ObjectPropertyNaming:
active: true active: true
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
propertyPattern: '[A-Za-z][_A-Za-z0-9]*' propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
PackageNaming: PackageNaming:
active: true active: true
packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$' packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
TopLevelPropertyNaming: TopLevelPropertyNaming:
active: true active: true
constantPattern: '[A-Z][_A-Z0-9]*' constantPattern: '[A-Z][_A-Z0-9]*'
propertyPattern: '[a-z][A-Za-z\d]*' propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern: '(_)?[a-z][A-Za-z0-9]*' privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
VariableMaxLength: VariableMaxLength:
active: false active: false
maximumVariableNameLength: 64 maximumVariableNameLength: 64
@ -253,130 +348,256 @@ naming:
variablePattern: '[a-z][A-Za-z0-9]*' variablePattern: '[a-z][A-Za-z0-9]*'
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^' excludeClassPattern: '$^'
ignoreOverridden: true
performance: performance:
active: true active: true
ArrayPrimitive:
active: true
ForEachOnRange: ForEachOnRange:
active: true active: true
SpreadOperator: SpreadOperator:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
UnnecessaryTemporaryInstantiation: UnnecessaryTemporaryInstantiation:
active: true active: true
potential-bugs: potential-bugs:
active: true active: true
AvoidReferentialEquality:
active: false
forbiddenTypePatterns:
- 'kotlin.String'
CastToNullableType:
active: false
Deprecation:
active: false
DontDowncastCollectionTypes:
active: false
DoubleMutabilityForCollection:
active: false
DuplicateCaseInWhenExpression: DuplicateCaseInWhenExpression:
active: true active: true
EqualsAlwaysReturnsTrueOrFalse: EqualsAlwaysReturnsTrueOrFalse:
active: false active: true
EqualsWithHashCodeExist: EqualsWithHashCodeExist:
active: true active: true
ExitOutsideMain:
active: false
ExplicitGarbageCollectionCall: ExplicitGarbageCollectionCall:
active: true active: true
InvalidRange: HasPlatformType:
active: false active: false
IteratorHasNextCallsNextMethod: IgnoredReturnValue:
active: false active: false
IteratorNotThrowingNoSuchElementException: restrictToAnnotatedMethods: true
returnValueAnnotations:
- '*.CheckResult'
- '*.CheckReturnValue'
ignoreReturnValueAnnotations:
- '*.CanIgnoreReturnValue'
ImplicitDefaultLocale:
active: false active: false
ImplicitUnitReturnType:
active: false
allowExplicitReturnType: true
InvalidRange:
active: true
IteratorHasNextCallsNextMethod:
active: true
IteratorNotThrowingNoSuchElementException:
active: true
LateinitUsage: LateinitUsage:
active: false active: false
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" ignoreOnClassesPattern: ''
excludeAnnotatedProperties: "" MapGetWithNotNullAssertionOperator:
ignoreOnClassesPattern: "" active: false
MissingPackageDeclaration:
active: false
excludes: ['**/*.kts']
MissingWhenCase:
active: true
allowElseExpression: true
NullableToStringCall:
active: false
RedundantElseInWhen:
active: true
UnconditionalJumpStatementInLoop: UnconditionalJumpStatementInLoop:
active: false active: false
UnnecessaryNotNullOperator:
active: true
UnnecessarySafeCall:
active: true
UnreachableCatchBlock:
active: false
UnreachableCode: UnreachableCode:
active: true active: true
UnsafeCallOnNullableType: UnsafeCallOnNullableType:
active: false active: true
UnsafeCast: UnsafeCast:
active: true
UnusedUnaryOperator:
active: false active: false
UselessPostfixExpression: UselessPostfixExpression:
active: false active: false
WrongEqualsTypeParameter: WrongEqualsTypeParameter:
active: false active: true
style: style:
active: true active: true
ClassOrdering:
active: false
CollapsibleIfStatements: CollapsibleIfStatements:
active: true active: true
DataClassContainsFunctions: DataClassContainsFunctions:
active: false active: false
conversionFunctionPrefix: 'to' conversionFunctionPrefix: 'to'
DataClassShouldBeImmutable:
active: false
DestructuringDeclarationWithTooManyEntries:
active: false
maxDestructuringEntries: 3
EqualsNullCall: EqualsNullCall:
active: true
EqualsOnSignatureLine:
active: false
ExplicitCollectionElementAccessMethod:
active: false
ExplicitItLambdaParameter:
active: false active: false
ExpressionBodySyntax: ExpressionBodySyntax:
active: false active: false
includeLineWrapping: false
ForbiddenComment: ForbiddenComment:
active: true active: true
values: 'TODO:,FIXME:,STOPSHIP:' values:
- 'FIXME:'
- 'STOPSHIP:'
- 'TODO:'
allowedPatterns: ''
customMessage: ''
ForbiddenImport: ForbiddenImport:
active: false active: false
imports: '' imports: []
FunctionOnlyReturningConstant: forbiddenPatterns: ''
ForbiddenMethodCall:
active: false active: false
methods:
- 'kotlin.io.print'
- 'kotlin.io.println'
ForbiddenPublicDataClass:
active: true
excludes: ['**']
ignorePackages:
- '*.internal'
- '*.internal.*'
ForbiddenVoid:
active: false
ignoreOverridden: false
ignoreUsageInGenerics: false
FunctionOnlyReturningConstant:
active: true
ignoreOverridableFunction: true ignoreOverridableFunction: true
excludedFunctions: 'describeContents' ignoreActualFunction: true
excludedFunctions: ''
LibraryCodeMustSpecifyReturnType:
active: true
excludes: ['**']
LibraryEntitiesShouldNotBePublic:
active: true
excludes: ['**']
LoopWithTooManyJumpStatements: LoopWithTooManyJumpStatements:
active: false active: false
maxJumpCount: 1 maxJumpCount: 1
MagicNumber: MagicNumber:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" ignoreNumbers:
ignoreNumbers: '-1,0,1,2' - '-1'
ignoreHashCodeFunction: false - '0'
ignorePropertyDeclaration: false - '1'
- '2'
ignoreHashCodeFunction: true
ignorePropertyDeclaration: true
ignoreLocalVariableDeclaration: false
ignoreConstantDeclaration: true ignoreConstantDeclaration: true
ignoreCompanionObjectPropertyDeclaration: true ignoreCompanionObjectPropertyDeclaration: true
ignoreAnnotation: false ignoreAnnotation: false
ignoreNamedArgument: true ignoreNamedArgument: true
ignoreEnums: false ignoreEnums: false
ignoreRanges: false
ignoreExtensionFunctions: true
MandatoryBracesIfStatements:
active: true
MandatoryBracesLoops:
active: false
MaxLineLength: MaxLineLength:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**"
maxLineLength: 120 maxLineLength: 120
excludePackageStatements: false excludePackageStatements: true
excludeImportStatements: false excludeImportStatements: true
excludeCommentStatements: false
MayBeConst: MayBeConst:
active: true active: true
ModifierOrder: ModifierOrder:
active: true active: true
NestedClassesVisibility: MultilineLambdaItParameter:
active: false active: false
NestedClassesVisibility:
active: true
NewLineAtEndOfFile: NewLineAtEndOfFile:
active: true active: true
NoTabs: NoTabs:
active: true active: true
ObjectLiteralToLambda:
active: false
OptionalAbstractKeyword: OptionalAbstractKeyword:
active: true active: true
OptionalUnit: OptionalUnit:
active: false active: false
OptionalWhenBraces: OptionalWhenBraces:
active: false active: false
PreferToOverPairSyntax:
active: false
ProtectedMemberInFinalClass: ProtectedMemberInFinalClass:
active: true
RedundantExplicitType:
active: false
RedundantHigherOrderMapUsage:
active: false active: false
RedundantVisibilityModifierRule: RedundantVisibilityModifierRule:
active: false active: false
ReturnCount: ReturnCount:
active: true active: true
max: 3 max: 3
excludedFunctions: "equals" excludedFunctions: 'equals'
excludeLabeled: false
excludeReturnFromLambda: true
excludeGuardClauses: false
SafeCast: SafeCast:
active: true active: true
SerialVersionUIDInSerializableClass: SerialVersionUIDInSerializableClass:
active: false active: true
SpacingBetweenPackageAndImports: SpacingBetweenPackageAndImports:
active: true active: true
ThrowsCount: ThrowsCount:
active: true active: true
max: 2 max: 2
excludeGuardClauses: false
TrailingWhitespace: TrailingWhitespace:
active: false active: false
UnderscoresInNumericLiterals:
active: false
acceptableLength: 4
UnnecessaryAbstractClass: UnnecessaryAbstractClass:
active: true active: true
UnnecessaryAnnotationUseSiteTarget:
active: false
UnnecessaryApply:
active: true
UnnecessaryFilter:
active: false
UnnecessaryInheritance: UnnecessaryInheritance:
active: true
UnnecessaryLet:
active: false active: false
UnnecessaryParentheses: UnnecessaryParentheses:
active: false active: false
@ -384,14 +605,44 @@ style:
active: false active: false
UnusedImports: UnusedImports:
active: false active: false
UnusedPrivateClass:
active: true
UnusedPrivateMember: UnusedPrivateMember:
active: true
allowedNames: '(_|ignored|expected|serialVersionUID)'
ignoreAnnotated: ['Composable']
UseAnyOrNoneInsteadOfFind:
active: false
UseArrayLiteralsInAnnotations:
active: false
UseCheckNotNull:
active: true
UseCheckOrError:
active: false active: false
UseDataClass: UseDataClass:
active: false active: false
excludeAnnotatedClasses: "" allowVars: false
UtilityClassWithPublicConstructor: UseEmptyCounterpart:
active: false
UseIfEmptyOrIfBlank:
active: false
UseIfInsteadOfWhen:
active: false
UseIsNullOrEmpty:
active: false active: false
UseOrEmpty:
active: true
UseRequire:
active: true
UseRequireNotNull:
active: true
UselessCallOnNotNull:
active: true
UtilityClassWithPublicConstructor:
active: true
VarCouldBeVal:
active: true
WildcardImport: WildcardImport:
active: true active: true
excludes: "**/*Test.kt, **/*Spec.kt, **/test/**, **/androidTest/**" excludeImports:
excludeImports: 'java.util.*' - 'java.util.*'

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save