diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 3cf7a594b..8a1f88ab7 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -219,59 +219,56 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback if (sessionObserver == null) sessionObserver = subscribeToSessions() - if (navHost.navController.currentDestination?.id == R.id.browserFragment) return - @IdRes var fragmentId: Int? = null - val directions = if (!navHost.navController.popBackStack(R.id.browserFragment, false)) { - when (from) { - BrowserDirection.FromGlobal -> - NavGraphDirections.actionGlobalBrowser(customTabSessionId) - BrowserDirection.FromHome -> { - fragmentId = R.id.homeFragment - HomeFragmentDirections.actionHomeFragmentToBrowserFragment(customTabSessionId) - } - BrowserDirection.FromSearch -> { - fragmentId = R.id.searchFragment - SearchFragmentDirections.actionSearchFragmentToBrowserFragment( - customTabSessionId - ) - } - BrowserDirection.FromSettings -> { - fragmentId = R.id.settingsFragment - SettingsFragmentDirections.actionSettingsFragmentToBrowserFragment( - customTabSessionId - ) - } - BrowserDirection.FromBookmarks -> { - fragmentId = R.id.bookmarkFragment - BookmarkFragmentDirections.actionBookmarkFragmentToBrowserFragment( - customTabSessionId - ) - } - BrowserDirection.FromBookmarksFolderSelect -> { - fragmentId = R.id.bookmarkSelectFolderFragment - SelectBookmarkFolderFragmentDirections - .actionBookmarkSelectFolderFragmentToBrowserFragment(customTabSessionId) - } - BrowserDirection.FromHistory -> { - fragmentId = R.id.historyFragment - HistoryFragmentDirections.actionHistoryFragmentToBrowserFragment( - customTabSessionId - ) - } - BrowserDirection.FromExceptions -> { - fragmentId = R.id.exceptionsFragment - ExceptionsFragmentDirections.actionExceptionsFragmentToBrowserFragment( - customTabSessionId - ) - } - } - } else { - null + with(navHost.navController) { + if (currentDestination?.id == R.id.browserFragment || popBackStack(R.id.browserFragment, false)) return } - directions?.let { - navHost.navController.nav(fragmentId, it) + @IdRes var fragmentId: Int? = null + val directions = when (from) { + BrowserDirection.FromGlobal -> + NavGraphDirections.actionGlobalBrowser(customTabSessionId) + BrowserDirection.FromHome -> { + fragmentId = R.id.homeFragment + HomeFragmentDirections.actionHomeFragmentToBrowserFragment(customTabSessionId) + } + BrowserDirection.FromSearch -> { + fragmentId = R.id.searchFragment + SearchFragmentDirections.actionSearchFragmentToBrowserFragment( + customTabSessionId + ) + } + BrowserDirection.FromSettings -> { + fragmentId = R.id.settingsFragment + SettingsFragmentDirections.actionSettingsFragmentToBrowserFragment( + customTabSessionId + ) + } + BrowserDirection.FromBookmarks -> { + fragmentId = R.id.bookmarkFragment + BookmarkFragmentDirections.actionBookmarkFragmentToBrowserFragment( + customTabSessionId + ) + } + BrowserDirection.FromBookmarksFolderSelect -> { + fragmentId = R.id.bookmarkSelectFolderFragment + SelectBookmarkFolderFragmentDirections + .actionBookmarkSelectFolderFragmentToBrowserFragment(customTabSessionId) + } + BrowserDirection.FromHistory -> { + fragmentId = R.id.historyFragment + HistoryFragmentDirections.actionHistoryFragmentToBrowserFragment( + customTabSessionId + ) + } + BrowserDirection.FromExceptions -> { + fragmentId = R.id.exceptionsFragment + ExceptionsFragmentDirections.actionExceptionsFragmentToBrowserFragment( + customTabSessionId + ) + } } + + navHost.navController.nav(fragmentId, directions) } private fun load( @@ -314,11 +311,11 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback var urlLoading: String? = null override fun onLoadingStateChanged(session: Session, loading: Boolean) { - super.onLoadingStateChanged(session, loading) - - if (loading) urlLoading = session.url - else if (urlLoading != null && !session.private) + if (loading) { + urlLoading = session.url + } else if (urlLoading != null && !session.private) { components.analytics.metrics.track(Event.UriOpened) + } } } @@ -360,24 +357,20 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback return object : SessionManager.Observer { override fun onAllSessionsRemoved() { - super.onAllSessionsRemoved() components.core.sessionManager.sessions.forEach { it.unregister(singleSessionObserver) } } override fun onSessionAdded(session: Session) { - super.onSessionAdded(session) session.register(singleSessionObserver, this@HomeActivity) } override fun onSessionRemoved(session: Session) { - super.onSessionRemoved(session) session.unregister(singleSessionObserver) } override fun onSessionsRestored() { - super.onSessionsRestored() components.core.sessionManager.sessions.forEach { it.register(singleSessionObserver, this@HomeActivity) } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 8229c558b..92442bab5 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -4,9 +4,6 @@ package org.mozilla.fenix.browser -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context import android.content.Intent import android.content.pm.ActivityInfo import android.os.Bundle @@ -19,7 +16,6 @@ import android.widget.RadioButton import androidx.appcompat.app.AppCompatActivity import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat -import androidx.core.content.getSystemService import androidx.core.net.toUri import androidx.fragment.app.Fragment import androidx.lifecycle.Observer @@ -55,6 +51,7 @@ import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissionsFeature import mozilla.components.feature.sitepermissions.SitePermissionsRules import mozilla.components.lib.state.ext.consumeFrom +import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.support.base.feature.BackHandler import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.ktx.android.view.exitImmersiveModeIfNeeded @@ -74,7 +71,6 @@ import org.mozilla.fenix.components.FindInPageIntegration import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.metrics.Event -import org.mozilla.fenix.components.metrics.Event.BrowserMenuItemTapped.Item import org.mozilla.fenix.components.toolbar.SearchAction import org.mozilla.fenix.components.toolbar.SearchState import org.mozilla.fenix.components.toolbar.ToolbarComponent @@ -82,6 +78,7 @@ import org.mozilla.fenix.components.toolbar.ToolbarIntegration import org.mozilla.fenix.components.toolbar.ToolbarMenu import org.mozilla.fenix.components.toolbar.ToolbarUIView import org.mozilla.fenix.components.toolbar.ToolbarViewModel +import org.mozilla.fenix.components.toolbar.trackToolbarItemInteraction import org.mozilla.fenix.customtabs.CustomTabsIntegration import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.enterToImmersiveMode @@ -89,7 +86,6 @@ import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.toTab import org.mozilla.fenix.home.sessioncontrol.SessionControlChange -import org.mozilla.fenix.home.sessioncontrol.TabCollection import org.mozilla.fenix.lib.Do import org.mozilla.fenix.mvi.ActionBusFactory import org.mozilla.fenix.mvi.getAutoDisposeObservable @@ -131,15 +127,17 @@ class BrowserFragment : Fragment(), BackHandler { var customTabSessionId: String? = null + /* override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) -// Disabled while awaiting a better solution to #3209 -// postponeEnterTransition() -// sharedElementEnterTransition = -// TransitionInflater.from(context).inflateTransition(android.R.transition.move).setDuration( -// SHARED_TRANSITION_MS -// ) + // Disabled while awaiting a better solution to #3209 + postponeEnterTransition() + sharedElementEnterTransition = + TransitionInflater.from(context).inflateTransition(android.R.transition.move).setDuration( + SHARED_TRANSITION_MS + ) } + */ @SuppressWarnings("ComplexMethod") override fun onCreateView( @@ -502,7 +500,8 @@ class BrowserFragment : Fragment(), BackHandler { ) } is SearchAction.ToolbarMenuItemTapped -> { - trackToolbarItemInteraction(it) + val metrics = requireComponents.analytics.metrics + trackToolbarItemInteraction(metrics, it) handleToolbarItemInteraction(it) } } @@ -625,31 +624,6 @@ class BrowserFragment : Fragment(), BackHandler { promptsFeature.withFeature { it.onActivityResult(requestCode, resultCode, data) } } - // This method triggers the complexity warning. However it's actually not that hard to understand. - @SuppressWarnings("ComplexMethod") - private fun trackToolbarItemInteraction(action: SearchAction.ToolbarMenuItemTapped) { - val item = when (action.item) { - ToolbarMenu.Item.Back -> Item.BACK - ToolbarMenu.Item.Forward -> Item.FORWARD - ToolbarMenu.Item.Reload -> Item.RELOAD - ToolbarMenu.Item.Stop -> Item.STOP - ToolbarMenu.Item.Settings -> Item.SETTINGS - ToolbarMenu.Item.Library -> Item.LIBRARY - is ToolbarMenu.Item.RequestDesktop -> - if (action.item.isChecked) Item.DESKTOP_VIEW_ON else Item.DESKTOP_VIEW_OFF - ToolbarMenu.Item.NewPrivateTab -> Item.NEW_PRIVATE_TAB - ToolbarMenu.Item.FindInPage -> Item.FIND_IN_PAGE - ToolbarMenu.Item.ReportIssue -> Item.REPORT_SITE_ISSUE - ToolbarMenu.Item.Help -> Item.HELP - ToolbarMenu.Item.NewTab -> Item.NEW_TAB - ToolbarMenu.Item.OpenInFenix -> Item.OPEN_IN_FENIX - ToolbarMenu.Item.Share -> Item.SHARE - ToolbarMenu.Item.SaveToCollection -> Item.SAVE_TO_COLLECTION - } - - requireComponents.analytics.metrics.track(Event.BrowserMenuItemTapped(item)) - } - // This method triggers the complexity warning. However it's actually not that hard to understand. @SuppressWarnings("ComplexMethod") private fun handleToolbarItemInteraction(action: SearchAction.ToolbarMenuItemTapped) { @@ -790,60 +764,43 @@ class BrowserFragment : Fragment(), BackHandler { } private fun getSessionById(): Session? { - val components = context?.components ?: return null + val sessionManager = context?.components?.core?.sessionManager ?: return null return if (customTabSessionId != null) { - components.core.sessionManager.findSessionById(customTabSessionId!!) + sessionManager.findSessionById(customTabSessionId!!) } else { - components.core.sessionManager.selectedSession + sessionManager.selectedSession } } - private fun getAppropriateLayoutGravity() = if (customTabSessionId != null) { - Gravity.TOP - } else { - Gravity.BOTTOM - } + private fun getAppropriateLayoutGravity() = if (customTabSessionId != null) Gravity.TOP else Gravity.BOTTOM - private fun Session.copyUrl(context: Context) { - context.getSystemService()?.apply { - primaryClip = ClipData.newPlainText(url, url) - } - } - - private fun subscribeToTabCollections(): Observer> { - val observer = Observer> { + private fun subscribeToTabCollections() = + Observer> { requireComponents.core.tabCollectionStorage.cachedTabCollections = it getManagedEmitter().onNext(SessionControlChange.CollectionsChange(it)) + }.also { observer -> + requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer) } - requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer) - return observer - } private fun subscribeToSession(): Session.Observer { - val observer = object : Session.Observer { + return object : Session.Observer { override fun onLoadingStateChanged(session: Session, loading: Boolean) { if (!loading) { updateBookmarkState(session) quickActionSheetStore.dispatch(QuickActionSheetAction.BounceNeededChange) } - - super.onLoadingStateChanged(session, loading) } override fun onUrlChanged(session: Session, url: String) { - super.onUrlChanged(session, url) updateBookmarkState(session) updateAppLinksState(session) } - } - getSessionById()?.register(observer, this) - return observer + }.also { observer -> getSessionById()?.register(observer, this) } } private fun subscribeToSessions(): SessionManager.Observer { return object : SessionManager.Observer { override fun onSessionSelected(session: Session) { - super.onSessionSelected(session) (activity as HomeActivity).updateThemeForSession(session) updateBookmarkState(session) } @@ -883,27 +840,20 @@ class BrowserFragment : Fragment(), BackHandler { private val collectionStorageObserver = object : TabCollectionStorage.Observer { override fun onCollectionCreated(title: String, sessions: List) { - super.onCollectionCreated(title, sessions) showTabSavedToCollectionSnackbar() } - override fun onTabsAdded( - tabCollection: mozilla.components.feature.tab.collections.TabCollection, - sessions: List - ) { - super.onTabsAdded(tabCollection, sessions) + override fun onTabsAdded(tabCollection: TabCollection, sessions: List) { showTabSavedToCollectionSnackbar() } } private fun showTabSavedToCollectionSnackbar() { - context?.let { context: Context -> - view?.let { view: View -> - val string = context.getString(R.string.create_collection_tab_saved) - FenixSnackbar.make(view, Snackbar.LENGTH_SHORT).setText(string) - .setAnchorView(toolbarComponent.uiView.view) - .show() - } + view?.let { view -> + FenixSnackbar.make(view, Snackbar.LENGTH_SHORT) + .setText(view.context.getString(R.string.create_collection_tab_saved)) + .setAnchorView(toolbarComponent.uiView.view) + .show() } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMetrics.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMetrics.kt new file mode 100644 index 000000000..f952f1a42 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMetrics.kt @@ -0,0 +1,36 @@ +/* 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.components.toolbar + +import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.components.metrics.MetricController + +// This method triggers the complexity warning. However it's actually not that hard to understand. +@SuppressWarnings("ComplexMethod") +fun trackToolbarItemInteraction(metrics: MetricController, action: SearchAction.ToolbarMenuItemTapped) { + val item = when (action.item) { + ToolbarMenu.Item.Back -> Event.BrowserMenuItemTapped.Item.BACK + ToolbarMenu.Item.Forward -> Event.BrowserMenuItemTapped.Item.FORWARD + ToolbarMenu.Item.Reload -> Event.BrowserMenuItemTapped.Item.RELOAD + ToolbarMenu.Item.Stop -> Event.BrowserMenuItemTapped.Item.STOP + ToolbarMenu.Item.Settings -> Event.BrowserMenuItemTapped.Item.SETTINGS + ToolbarMenu.Item.Library -> Event.BrowserMenuItemTapped.Item.LIBRARY + is ToolbarMenu.Item.RequestDesktop -> if (action.item.isChecked) { + Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON + } else { + Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_OFF + } + ToolbarMenu.Item.NewPrivateTab -> Event.BrowserMenuItemTapped.Item.NEW_PRIVATE_TAB + ToolbarMenu.Item.FindInPage -> Event.BrowserMenuItemTapped.Item.FIND_IN_PAGE + ToolbarMenu.Item.ReportIssue -> Event.BrowserMenuItemTapped.Item.REPORT_SITE_ISSUE + ToolbarMenu.Item.Help -> Event.BrowserMenuItemTapped.Item.HELP + ToolbarMenu.Item.NewTab -> Event.BrowserMenuItemTapped.Item.NEW_TAB + ToolbarMenu.Item.OpenInFenix -> Event.BrowserMenuItemTapped.Item.OPEN_IN_FENIX + ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE + ToolbarMenu.Item.SaveToCollection -> Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION + } + + metrics.track(Event.BrowserMenuItemTapped(item)) +} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index b680c7c71..3fcd5b0aa 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -19,7 +19,10 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.Observer +import androidx.lifecycle.OnLifecycleEvent import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.NavHostFragment.findNavController @@ -32,13 +35,14 @@ import kotlinx.android.synthetic.main.fragment_home.view.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext import mozilla.components.browser.menu.BrowserMenu import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.Profile +import mozilla.components.feature.tab.collections.TabCollection import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.BOTTOM import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.END import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder.Side.START @@ -69,7 +73,6 @@ import org.mozilla.fenix.home.sessioncontrol.SessionControlState import org.mozilla.fenix.home.sessioncontrol.SessionControlViewModel import org.mozilla.fenix.home.sessioncontrol.Tab import org.mozilla.fenix.home.sessioncontrol.TabAction -import org.mozilla.fenix.home.sessioncontrol.TabCollection import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionViewHolder import org.mozilla.fenix.lib.Do import org.mozilla.fenix.mvi.ActionBusFactory @@ -84,37 +87,23 @@ import kotlin.math.roundToInt @SuppressWarnings("TooManyFunctions", "LargeClass") class HomeFragment : Fragment(), AccountObserver { private val bus = ActionBusFactory.get(this) - private var tabCollectionObserver: Observer>? = null private val singleSessionObserver = object : Session.Observer { override fun onTitleChanged(session: Session, title: String) { - super.onTitleChanged(session, title) - if (deleteAllSessionsJob != null) return - emitSessionChanges() + if (deleteAllSessionsJob == null) emitSessionChanges() } } - private lateinit var sessionObserver: BrowserSessionsObserver - private val collectionStorageObserver = object : TabCollectionStorage.Observer { override fun onCollectionCreated(title: String, sessions: List) { - super.onCollectionCreated(title, sessions) scrollAndAnimateCollection(sessions.size) } - override fun onTabsAdded( - tabCollection: mozilla.components.feature.tab.collections.TabCollection, - sessions: List - ) { - super.onTabsAdded(tabCollection, sessions) + override fun onTabsAdded(tabCollection: TabCollection, sessions: List) { scrollAndAnimateCollection(sessions.size, tabCollection) } - override fun onCollectionRenamed( - tabCollection: mozilla.components.feature.tab.collections.TabCollection, - title: String - ) { - super.onCollectionRenamed(tabCollection, title) + override fun onCollectionRenamed(tabCollection: TabCollection, title: String) { showRenamedSnackbar() } } @@ -152,9 +141,10 @@ class HomeFragment : Fragment(), AccountObserver { // sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move) // .setDuration(SHARED_TRANSITION_MS) - sessionObserver = BrowserSessionsObserver(sessionManager, singleSessionObserver) { + val sessionObserver = BrowserSessionsObserver(sessionManager, singleSessionObserver) { emitSessionChanges() } + lifecycle.addObserver(sessionObserver) if (!onboarding.userHasBeenOnboarded()) { requireComponents.analytics.metrics.track(Event.OpenedAppFirstRun) @@ -229,17 +219,14 @@ class HomeFragment : Fragment(), AccountObserver { setupHomeMenu() - viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) { + viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) { val iconSize = resources.getDimension(R.dimen.preference_icon_drawable_size).toInt() - val searchIcon = requireComponents.search.searchEngineManager.getDefaultSearchEngine( - requireContext() - ).let { - BitmapDrawable(resources, it.icon) - } + val searchEngine = requireComponents.search.searchEngineManager.getDefaultSearchEngine(requireContext()) + val searchIcon = BitmapDrawable(resources, searchEngine.icon) searchIcon.setBounds(0, 0, iconSize, iconSize) - runBlocking(Dispatchers.Main) { + withContext(Dispatchers.Main) { search_engine_icon?.setImageDrawable(searchIcon) } } @@ -250,9 +237,8 @@ class HomeFragment : Fragment(), AccountObserver { orientation = BrowserMenu.Orientation.DOWN ) } - val roundToInt = + view.toolbar.compoundDrawablePadding = (toolbarPaddingDp * Resources.getSystem().displayMetrics.density).roundToInt() - view.toolbar.compoundDrawablePadding = roundToInt view.toolbar.setOnClickListener { invokePendingDeleteJobs() onboarding.finish() @@ -328,22 +314,12 @@ class HomeFragment : Fragment(), AccountObserver { override fun onStart() { super.onStart() - sessionObserver.onStart() - tabCollectionObserver = subscribeToTabCollections() + subscribeToTabCollections() // We only want this observer live just before we navigate away to the collection creation screen requireComponents.core.tabCollectionStorage.unregister(collectionStorageObserver) } - override fun onStop() { - sessionObserver.onStop() - tabCollectionObserver?.let { - requireComponents.core.tabCollectionStorage.getCollections().removeObserver(it) - } - - super.onStop() - } - private fun handleOnboardingAction(action: OnboardingAction) { Do exhaustive when (action) { is OnboardingAction.Finish -> { @@ -616,12 +592,12 @@ class HomeFragment : Fragment(), AccountObserver { } private fun subscribeToTabCollections(): Observer> { - val observer = Observer> { + return Observer> { requireComponents.core.tabCollectionStorage.cachedTabCollections = it getManagedEmitter().onNext(SessionControlChange.CollectionsChange(it)) + }.also { observer -> + requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer) } - requireComponents.core.tabCollectionStorage.getCollections().observe(this, observer) - return observer } private fun removeAllTabsWithUndo(listOfSessionsToDelete: List) { @@ -687,11 +663,6 @@ class HomeFragment : Fragment(), AccountObserver { return sessionManager.filteredSessions(isPrivate, notPendingDeletion) } - private fun emitAccountChanges() { - val mode = currentMode() - getManagedEmitter().onNext(SessionControlChange.ModeChange(mode)) - } - private fun showCollectionCreationFragment( selectedTabId: String? = null, selectedTabCollection: TabCollection? = null, @@ -746,21 +717,15 @@ class HomeFragment : Fragment(), AccountObserver { Mode.Normal } - override fun onAuthenticationProblems() { - emitAccountChanges() + private fun emitAccountChanges() { + val mode = currentMode() + getManagedEmitter().onNext(SessionControlChange.ModeChange(mode)) } - override fun onAuthenticated(account: OAuthAccount) { - emitAccountChanges() - } - - override fun onLoggedOut() { - emitAccountChanges() - } - - override fun onProfileUpdated(profile: Profile) { - emitAccountChanges() - } + override fun onAuthenticationProblems() = emitAccountChanges() + override fun onAuthenticated(account: OAuthAccount) = emitAccountChanges() + override fun onLoggedOut() = emitAccountChanges() + override fun onProfileUpdated(profile: Profile) = emitAccountChanges() private fun scrollAndAnimateCollection(tabsAddedToCollectionSize: Int, changedCollection: TabCollection? = null) { if (view != null) { @@ -898,15 +863,12 @@ private class BrowserSessionsObserver( private val manager: SessionManager, private val observer: Session.Observer, private val onChanged: () -> Unit -) { - - // TODO This is workaround. Should be removed when [mozilla.components.support.base.observer.ObserverRegistry] - // will not allow to subscribe to single session more than once. - private val observedSessions = mutableSetOf() +) : LifecycleObserver { /** * Start observing */ + @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onStart() { manager.register(managerObserver) subscribeToAll() @@ -915,6 +877,7 @@ private class BrowserSessionsObserver( /** * Stop observing (will not receive updates till next [onStop] call) */ + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onStop() { manager.unregister(managerObserver) unsubscribeFromAll() @@ -929,21 +892,14 @@ private class BrowserSessionsObserver( } private fun subscribeTo(session: Session) { - if (!observedSessions.contains(session)) { - session.register(observer) - observedSessions += session - } + session.register(observer) } private fun unsubscribeFrom(session: Session) { - if (observedSessions.contains(session)) { - session.unregister(observer) - observedSessions -= session - } + session.unregister(observer) } private val managerObserver = object : SessionManager.Observer { - override fun onSessionAdded(session: Session) { subscribeTo(session) onChanged() diff --git a/app/src/main/java/org/mozilla/fenix/lib/Do.kt b/app/src/main/java/org/mozilla/fenix/lib/Do.kt index ba6062a90..396ecd236 100644 --- a/app/src/main/java/org/mozilla/fenix/lib/Do.kt +++ b/app/src/main/java/org/mozilla/fenix/lib/Do.kt @@ -5,5 +5,14 @@ package org.mozilla.fenix.lib object Do { + + /** + * Indicates to the linter that the following when statement should be exhaustive. + * + * @sample Do exhaustive when (bool) { + * true -> Unit + * false -> Unit + * } + */ inline infix fun exhaustive(any: T?) = any } diff --git a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataFragment.kt index e75e529ce..daa8cd94c 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataFragment.kt @@ -40,30 +40,11 @@ class DeleteBrowsingDataFragment : Fragment() { super.onViewCreated(view, savedInstanceState) sessionObserver = object : SessionManager.Observer { - override fun onSessionAdded(session: Session) { - super.onSessionAdded(session) - updateTabCount() - } - - override fun onSessionRemoved(session: Session) { - super.onSessionRemoved(session) - updateTabCount() - } - - override fun onSessionSelected(session: Session) { - super.onSessionSelected(session) - updateTabCount() - } - - override fun onSessionsRestored() { - super.onSessionsRestored() - updateTabCount() - } - - override fun onAllSessionsRemoved() { - super.onAllSessionsRemoved() - updateTabCount() - } + override fun onSessionAdded(session: Session) = updateTabCount() + override fun onSessionRemoved(session: Session) = updateTabCount() + override fun onSessionSelected(session: Session) = updateTabCount() + override fun onSessionsRestored() = updateTabCount() + override fun onAllSessionsRemoved() = updateTabCount() } requireComponents.core.sessionManager.register(sessionObserver, owner = this) diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsSheetDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsSheetDialogFragment.kt index 49fb5a471..4f7466d4d 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsSheetDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsSheetDialogFragment.kt @@ -244,7 +244,6 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() { private val sessionObserver = object : Session.Observer { override fun onUrlChanged(session: Session, url: String) { - super.onUrlChanged(session, url) lifecycleScope.launch(Dispatchers.IO) { val host = session.url.toUri()?.host val sitePermissions: SitePermissions? = host?.let { @@ -265,7 +264,6 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() { } override fun onTrackerBlockingEnabledChanged(session: Session, blockingEnabled: Boolean) { - super.onTrackerBlockingEnabledChanged(session, blockingEnabled) getManagedEmitter().onNext( QuickSettingsChange.Change( session.url, @@ -277,7 +275,6 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() { } override fun onSecurityChanged(session: Session, securityInfo: Session.SecurityInfo) { - super.onSecurityChanged(session, securityInfo) getManagedEmitter().onNext( QuickSettingsChange.Change( session.url,