Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49dbc2c7 authored by András Kurucz's avatar András Kurucz Committed by Android (Google) Code Review
Browse files

Merge changes I54cf91bd,I547668b5 into main

* changes:
  Make BigPictureIconManager reload the image on each icon update
  Disable bigpicture lazy loading for unsupported icons
parents 06930c9e 1063ac01
Loading
Loading
Loading
Loading
+15 −16
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ constructor(
            this.lastLoadingJob?.cancel()
            this.lastLoadingJob =
                when {
                    skipLazyLoading(state.icon) -> null
                    state is Empty && shown -> state.icon?.let(::startLoadingJob)
                    state is PlaceHolder && shown -> startLoadingJob(state.icon)
                    state is FullImage && !shown ->
@@ -119,12 +120,6 @@ constructor(
            return Runnable {}
        }

        if (displayedState.iconSameAs(icon)) {
            // We're already handling this icon, nothing to do here.
            log("skipping updateIcon for consumer:$drawableConsumer with icon:$icon")
            return Runnable {}
        }

        this.drawableConsumer = drawableConsumer
        this.displayedState = Empty(icon)
        this.lastLoadingJob?.cancel()
@@ -144,7 +139,7 @@ constructor(
    private fun loadImageOrPlaceHolderSync(icon: Icon?): Drawable? {
        icon ?: return null

        if (viewShown) {
        if (viewShown || skipLazyLoading(icon)) {
            return loadImageSync(icon)
        }

@@ -228,6 +223,19 @@ constructor(
            }
        )

    /**
     * We don't support lazy-loading or set placeholders for bitmap and data based icons, because
     * they gonna stay in memory anyways.
     */
    private fun skipLazyLoading(icon: Icon?): Boolean =
        when (icon?.type) {
            Icon.TYPE_BITMAP,
            Icon.TYPE_ADAPTIVE_BITMAP,
            Icon.TYPE_DATA,
            null -> true
            else -> false
        }

    private fun log(msg: String) {
        if (DEBUG) {
            Log.d(TAG, "$msg state=${getDebugString()}")
@@ -242,15 +250,6 @@ constructor(
        data class PlaceHolder(override val icon: Icon, val drawableSize: Size) :
            DrawableState(icon)
        data class FullImage(override val icon: Icon, val drawableSize: Size) : DrawableState(icon)

        fun iconSameAs(other: Icon?): Boolean {
            val displayedIcon = icon
            return when {
                displayedIcon == null && other == null -> true
                displayedIcon != null && other != null -> displayedIcon.sameAs(other)
                else -> false
            }
        }
    }
}

+89 −8
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
    }
    private val unsupportedIcon by lazy {
        Icon.createWithBitmap(
            BitmapFactory.decodeResource(context.resources, R.drawable.dessert_zombiegingerbread)
            BitmapFactory.decodeResource(context.resources, R.drawable.dessert_donutburger)
        )
    }
    private val invalidIcon by lazy { Icon.createWithContentUri(Uri.parse("this.is/broken")) }
@@ -100,7 +100,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
        }

    @Test
    fun onIconUpdated_notSupportedType_fullImageLoaded() =
    fun onIconUpdated_unsupportedType_fullImageLoaded() =
        testScope.runTest {
            // WHEN update with an unsupported icon
            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
@@ -111,6 +111,16 @@ class BigPictureIconManagerTest : SysuiTestCase() {
            assertSize(drawableCaptor.value)
        }

    @Test
    fun onIconUpdated_withNull_drawableIsNull() =
        testScope.runTest {
            // WHEN update with null
            iconManager.updateIcon(mockConsumer, null).run()

            // THEN consumer is updated with null
            verify(mockConsumer).setImageDrawable(null)
        }

    @Test
    fun onIconUpdated_invalidIcon_drawableIsNull() =
        testScope.runTest {
@@ -152,6 +162,43 @@ class BigPictureIconManagerTest : SysuiTestCase() {
            assertSize(drawableCaptor.value)
        }

    @Test
    fun onIconUpdated_iconAlreadySetForTheSameIcon_loadsIconAgain() =
        testScope.runTest {
            // GIVEN an icon is set
            iconManager.updateIcon(mockConsumer, supportedIcon).run()
            // AND the view is shown
            iconManager.onViewShown(true)
            runCurrent()
            reset(mockConsumer)
            // WHEN the icon is set again
            iconManager.updateIcon(mockConsumer, supportedIcon).run()

            // THEN consumer is updated with the new image
            verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
            assertIsFullImage(drawableCaptor.value)
            assertSize(drawableCaptor.value)
        }

    @Test
    fun onIconUpdated_iconAlreadySetForUnsupportedIcon_loadsNewIcon() =
        testScope.runTest {
            // GIVEN an unsupported icon is set
            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
            // AND the view is shown
            iconManager.onViewShown(true)
            runCurrent()
            reset(mockConsumer)

            // WHEN a new icon is set
            iconManager.updateIcon(mockConsumer, supportedIcon).run()

            // THEN consumer is updated with the new image
            verify(mockConsumer).setImageDrawable(drawableCaptor.capture())
            assertIsFullImage(drawableCaptor.value)
            assertSize(drawableCaptor.value)
        }

    @Test
    fun onIconUpdated_supportedTypeButTooWide_resizedPlaceholderLoaded() =
        testScope.runTest {
@@ -249,12 +296,10 @@ class BigPictureIconManagerTest : SysuiTestCase() {
            verifyZeroInteractions(mockConsumer)
        }

    // nice to have tests

    @Test
    fun onViewShown_fullImageLoaded_nothingHappens() =
    fun onViewShown_unsupportedIconLoaded_nothingHappens() =
        testScope.runTest {
            // GIVEN full image is showing
            // GIVEN full image is showing for an unsupported icon
            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
            reset(mockConsumer)

@@ -266,11 +311,46 @@ class BigPictureIconManagerTest : SysuiTestCase() {
            verifyZeroInteractions(mockConsumer)
        }

    @Test
    fun onViewShown_nullSetForIcon_nothingHappens() =
        testScope.runTest {
            // GIVEN null is set for the icon
            iconManager.updateIcon(mockConsumer, null).run()
            reset(mockConsumer)

            // WHEN the view is shown
            iconManager.onViewShown(true)
            runCurrent()

            // THEN nothing happens
            verifyZeroInteractions(mockConsumer)
        }

    @Test
    fun onViewHidden_unsupportedIconLoadedAndViewIsShown_nothingHappens() =
        testScope.runTest {
            // GIVEN full image is showing for an unsupported icon
            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
            // AND the view is shown
            iconManager.onViewShown(true)
            runCurrent()
            reset(mockConsumer)

            // WHEN the view goes off the screen
            iconManager.onViewShown(false)
            // AND we wait a bit
            advanceTimeBy(FREE_IMAGE_DELAY_MS)
            runCurrent()

            // THEN nothing happens
            verifyZeroInteractions(mockConsumer)
        }

    @Test
    fun onViewHidden_placeholderShowing_nothingHappens() =
        testScope.runTest {
            // GIVEN placeholder image is showing
            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
            iconManager.updateIcon(mockConsumer, supportedIcon).run()
            reset(mockConsumer)

            // WHEN the view is hidden
@@ -296,6 +376,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
            iconManager.onViewShown(true)
            runCurrent()

            // THEN nothing happens
            verifyZeroInteractions(mockConsumer)
        }

@@ -303,7 +384,7 @@ class BigPictureIconManagerTest : SysuiTestCase() {
    fun onViewHidden_alreadyHidden_nothingHappens() =
        testScope.runTest {
            // GIVEN placeholder image is showing and the view is hidden
            iconManager.updateIcon(mockConsumer, unsupportedIcon).run()
            iconManager.updateIcon(mockConsumer, supportedIcon).run()
            iconManager.onViewShown(false)
            advanceTimeBy(FREE_IMAGE_DELAY_MS)
            runCurrent()