diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt index 46f81221d6..eb2a51bbb8 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt @@ -259,7 +259,7 @@ class SessionControlAdapter( return when (viewType) { TopPlaceholderViewHolder.LAYOUT_ID -> TopPlaceholderViewHolder(view) ButtonTipViewHolder.LAYOUT_ID -> ButtonTipViewHolder(view, interactor) - TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(view, interactor) + TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(view, viewLifecycleOwner, interactor) PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder( view, interactor diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt index 3bfa99e5cb..a30d57c84e 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolder.kt @@ -10,7 +10,8 @@ import android.view.View import android.widget.PopupWindow import androidx.appcompat.content.res.AppCompatResources.getDrawable import androidx.core.view.isVisible -import kotlinx.coroutines.CoroutineScope +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch @@ -28,6 +29,7 @@ import org.mozilla.fenix.utils.view.ViewHolder class TopSiteItemViewHolder( view: View, + private val viewLifecycleOwner: LifecycleOwner, private val interactor: TopSiteInteractor ) : ViewHolder(view) { private lateinit var topSite: TopSite @@ -83,7 +85,7 @@ class TopSiteItemViewHolder( if (topSite is TopSite.Provided) { binding.topSiteSubtitle.isVisible = true - CoroutineScope(IO).launch { + viewLifecycleOwner.lifecycleScope.launch(IO) { itemView.context.components.core.client.bitmapForUrl(topSite.imageUrl)?.let { bitmap -> withContext(Main) { binding.faviconImage.setImageBitmap(bitmap) diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitePagerViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitePagerViewHolder.kt index 4777d88f03..6941d5cc8c 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitePagerViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitePagerViewHolder.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.home.topsites import android.view.View import androidx.core.view.isVisible +import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import mozilla.components.feature.top.sites.TopSite @@ -18,11 +19,12 @@ import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor class TopSitePagerViewHolder( view: View, + viewLifecycleOwner: LifecycleOwner, interactor: TopSiteInteractor ) : RecyclerView.ViewHolder(view) { private val binding = ComponentTopSitesPagerBinding.bind(view) - private val topSitesPagerAdapter = TopSitesPagerAdapter(interactor) + private val topSitesPagerAdapter = TopSitesPagerAdapter(viewLifecycleOwner, interactor) private val pageIndicator = binding.pageIndicator private var currentPage = 0 diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteViewHolder.kt index a5c1631228..786b367b37 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSiteViewHolder.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.home.topsites import android.view.View +import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView import mozilla.components.feature.top.sites.TopSite import org.mozilla.fenix.R @@ -14,10 +15,11 @@ import org.mozilla.fenix.utils.AccessibilityGridLayoutManager class TopSiteViewHolder( view: View, + viewLifecycleOwner: LifecycleOwner, interactor: TopSiteInteractor ) : RecyclerView.ViewHolder(view) { - private val topSitesAdapter = TopSitesAdapter(interactor) + private val topSitesAdapter = TopSitesAdapter(viewLifecycleOwner, interactor) val binding = ComponentTopSitesBinding.bind(view) init { diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesAdapter.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesAdapter.kt index 579aca2892..85a11b3e3f 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesAdapter.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.home.topsites import android.view.LayoutInflater import android.view.ViewGroup +import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import mozilla.components.feature.top.sites.TopSite @@ -13,12 +14,13 @@ import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor import org.mozilla.fenix.perf.StartupTimeline class TopSitesAdapter( + private val viewLifecycleOwner: LifecycleOwner, private val interactor: TopSiteInteractor ) : ListAdapter(TopSitesDiffCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopSiteItemViewHolder { val view = LayoutInflater.from(parent.context) .inflate(TopSiteItemViewHolder.LAYOUT_ID, parent, false) - return TopSiteItemViewHolder(view, interactor) + return TopSiteItemViewHolder(view, viewLifecycleOwner, interactor) } override fun onBindViewHolder(holder: TopSiteItemViewHolder, position: Int) { diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt index 1a1c08c822..30f42fb7ea 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapter.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.home.topsites import android.view.LayoutInflater import android.view.ViewGroup import androidx.annotation.VisibleForTesting +import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import mozilla.components.feature.top.sites.TopSite @@ -15,13 +16,14 @@ import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder.Companion.TOP_SITES_PER_PAGE class TopSitesPagerAdapter( + private val viewLifecycleOwner: LifecycleOwner, private val interactor: TopSiteInteractor ) : ListAdapter, TopSiteViewHolder>(TopSiteListDiffCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopSiteViewHolder { val view = LayoutInflater.from(parent.context) .inflate(TopSiteViewHolder.LAYOUT_ID, parent, false) - return TopSiteViewHolder(view, interactor) + return TopSiteViewHolder(view, viewLifecycleOwner, interactor) } override fun onBindViewHolder( diff --git a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt index 7cef00f862..b6be453d75 100644 --- a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteItemViewHolderTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.home.topsites import android.view.LayoutInflater +import androidx.lifecycle.LifecycleOwner import io.mockk.every import io.mockk.mockk import io.mockk.verify @@ -26,6 +27,8 @@ class TopSiteItemViewHolderTest { private lateinit var binding: TopSiteItemBinding private lateinit var interactor: TopSiteInteractor + private lateinit var lifecycleOwner: LifecycleOwner + private val pocket = TopSite.Default( id = 1L, title = "Pocket", @@ -37,12 +40,14 @@ class TopSiteItemViewHolderTest { fun setup() { binding = TopSiteItemBinding.inflate(LayoutInflater.from(testContext)) interactor = mockk(relaxed = true) + lifecycleOwner = mockk(relaxed = true) + every { testContext.components.core.icons } returns BrowserIcons(testContext, mockk(relaxed = true)) } @Test fun `calls interactor on click`() { - TopSiteItemViewHolder(binding.root, interactor).bind(pocket) + TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(pocket) binding.topSiteItem.performClick() verify { interactor.onSelectTopSite(pocket) } @@ -51,7 +56,7 @@ class TopSiteItemViewHolderTest { @Test fun `calls interactor on long click`() { every { testContext.components.analytics } returns mockk(relaxed = true) - TopSiteItemViewHolder(binding.root, interactor).bind(pocket) + TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(pocket) binding.topSiteItem.performLongClick() verify { interactor.onTopSiteMenuOpened() } @@ -66,7 +71,7 @@ class TopSiteItemViewHolderTest { createdAt = 0 ) - TopSiteItemViewHolder(binding.root, interactor).bind(defaultTopSite) + TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(defaultTopSite) val pinIndicator = binding.topSiteTitle.compoundDrawables[0] assertNotNull(pinIndicator) @@ -81,7 +86,7 @@ class TopSiteItemViewHolderTest { createdAt = 0 ) - TopSiteItemViewHolder(binding.root, interactor).bind(pinnedTopSite) + TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(pinnedTopSite) val pinIndicator = binding.topSiteTitle.compoundDrawables[0] assertNotNull(pinIndicator) @@ -96,7 +101,7 @@ class TopSiteItemViewHolderTest { createdAt = 0 ) - TopSiteItemViewHolder(binding.root, interactor).bind(frecentTopSite) + TopSiteItemViewHolder(binding.root, lifecycleOwner, interactor).bind(frecentTopSite) val pinIndicator = binding.topSiteTitle.compoundDrawables[0] assertNull(pinIndicator) diff --git a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteViewHolderTest.kt index f3a8debf3e..9c994b217a 100644 --- a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSiteViewHolderTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.home.topsites import android.view.LayoutInflater +import androidx.lifecycle.LifecycleOwner import io.mockk.mockk import mozilla.components.feature.top.sites.TopSite import mozilla.components.support.test.robolectric.testContext @@ -20,17 +21,19 @@ import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor class TopSiteViewHolderTest { private lateinit var binding: ComponentTopSitesBinding + private lateinit var lifecycleOwner: LifecycleOwner private lateinit var interactor: TopSiteInteractor @Before fun setup() { binding = ComponentTopSitesBinding.inflate(LayoutInflater.from(testContext)) - interactor = mockk() + interactor = mockk(relaxed = true) + lifecycleOwner = mockk(relaxed = true) } @Test fun `binds list of top sites`() { - TopSiteViewHolder(binding.root, interactor).bind( + TopSiteViewHolder(binding.root, lifecycleOwner, interactor).bind( listOf( TopSite.Default( id = 1L, diff --git a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapterTest.kt b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapterTest.kt index f8daa3988c..e242ea9339 100644 --- a/app/src/test/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/topsites/TopSitesPagerAdapterTest.kt @@ -49,7 +49,7 @@ class TopSitesPagerAdapterTest { @Before fun setup() { - topSitesPagerAdapter = spyk(TopSitesPagerAdapter(mockk())) + topSitesPagerAdapter = spyk(TopSitesPagerAdapter(mockk(), mockk())) } @Test diff --git a/app/src/test/java/org/mozilla/fenix/perf/StartupReportFullyDrawnTest.kt b/app/src/test/java/org/mozilla/fenix/perf/StartupReportFullyDrawnTest.kt index aea82ad717..549588edc8 100644 --- a/app/src/test/java/org/mozilla/fenix/perf/StartupReportFullyDrawnTest.kt +++ b/app/src/test/java/org/mozilla/fenix/perf/StartupReportFullyDrawnTest.kt @@ -47,7 +47,7 @@ class StartupReportFullyDrawnTest { holderItemView = spyk(binding.root) every { activity.findViewById(R.id.rootContainer) } returns rootContainer every { holderItemView.context } returns activity - holder = TopSiteItemViewHolder(holderItemView, mockk()) + holder = TopSiteItemViewHolder(holderItemView, mockk(), mockk()) every { rootContainer.viewTreeObserver } returns viewTreeObserver every { holderItemView.viewTreeObserver } returns viewTreeObserver