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

Commit ab84e005 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Automerger Merge Worker
Browse files

Merge "Fix performance regressions" into tm-qpr-dev am: e8b79073 am: fb11299f

parents f06229bd fb11299f
Loading
Loading
Loading
Loading
+33 −31
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.shade

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.IdRes
import android.app.StatusBarManager
import android.content.res.Configuration
@@ -145,6 +146,14 @@ class LargeScreenShadeHeaderController @Inject constructor(
            updateListeners()
        }

    private var customizing = false
        set(value) {
            if (field != value) {
                field = value
                updateVisibility()
            }
        }

    /**
     * Whether the QQS/QS part of the shade is visible. This is particularly important in
     * Lockscreen, as the shade is visible but QS is not.
@@ -176,14 +185,9 @@ class LargeScreenShadeHeaderController @Inject constructor(
     */
    var shadeExpandedFraction = -1f
        set(value) {
            if (field != value) {
                val oldAlpha = header.alpha
            if (qsVisible && field != value) {
                header.alpha = ShadeInterpolation.getContentAlpha(value)
                field = value
                if ((oldAlpha == 0f && header.alpha > 0f) ||
                        (oldAlpha > 0f && header.alpha == 0f)) {
                    updateVisibility()
                }
            }
        }

@@ -318,6 +322,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
        dumpManager.registerDumpable(this)
        configurationController.addCallback(configurationControllerListener)
        demoModeController.addCallback(demoModeReceiver)
        statusBarIconController.addIconGroup(iconManager)
    }

    override fun onViewDetached() {
@@ -325,6 +330,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
        dumpManager.unregisterDumpable(this::class.java.simpleName)
        configurationController.removeCallback(configurationControllerListener)
        demoModeController.removeCallback(demoModeReceiver)
        statusBarIconController.removeIconGroup(iconManager)
    }

    fun disable(state1: Int, state2: Int, animate: Boolean) {
@@ -339,31 +345,10 @@ class LargeScreenShadeHeaderController @Inject constructor(
                .setDuration(duration)
                .alpha(if (show) 0f else 1f)
                .setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
                .setUpdateListener {
                    updateVisibility()
                }
                .setListener(endAnimationListener)
                .setListener(CustomizerAnimationListener(show))
                .start()
    }

    private val endAnimationListener = object : Animator.AnimatorListener {
        override fun onAnimationCancel(animation: Animator?) {
            clearListeners()
        }

        override fun onAnimationEnd(animation: Animator?) {
            clearListeners()
        }

        override fun onAnimationRepeat(animation: Animator?) {}

        override fun onAnimationStart(animation: Animator?) {}

        private fun clearListeners() {
            header.animate().setListener(null).setUpdateListener(null)
        }
    }

    private fun loadConstraints() {
        if (header is MotionLayout) {
            // Use resources.getXml instead of passing the resource id due to bug b/205018300
@@ -453,7 +438,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
    private fun updateVisibility() {
        val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
            View.GONE
        } else if (qsVisible && header.alpha > 0f) {
        } else if (qsVisible && !customizing) {
            View.VISIBLE
        } else {
            View.INVISIBLE
@@ -502,10 +487,8 @@ class LargeScreenShadeHeaderController @Inject constructor(
        if (visible) {
            updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
            qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
            statusBarIconController.addIconGroup(iconManager)
        } else {
            qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
            statusBarIconController.removeIconGroup(iconManager)
        }
    }

@@ -578,4 +561,23 @@ class LargeScreenShadeHeaderController @Inject constructor(

    @VisibleForTesting
    internal fun simulateViewDetached() = this.onViewDetached()

    inner class CustomizerAnimationListener(
            private val enteringCustomizing: Boolean,
    ) : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator?) {
            super.onAnimationEnd(animation)
            header.animate().setListener(null)
            if (enteringCustomizing) {
                customizing = true
            }
        }

        override fun onAnimationStart(animation: Animator?) {
            super.onAnimationStart(animation)
            if (!enteringCustomizing) {
                customizing = false
            }
        }
    }
}
+27 −50
Original line number Diff line number Diff line
package com.android.systemui.shade

import android.animation.Animator
import android.animation.ValueAnimator
import android.app.StatusBarManager
import android.content.Context
import android.testing.AndroidTestingRunner
@@ -44,6 +43,7 @@ import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.junit.MockitoJUnit
@@ -158,24 +158,24 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
    fun updateListeners_registersWhenVisible() {
        makeShadeVisible()
        verify(qsCarrierGroupController).setListening(true)
    }

    @Test
    fun statusIconsAddedWhenAttached() {
        verify(statusBarIconController).addIconGroup(any())
    }

    @Test
    fun shadeExpandedFraction_updatesAlpha() {
        makeShadeVisible()
        mLargeScreenShadeHeaderController.shadeExpandedFraction = 0.5f
        verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
    fun statusIconsRemovedWhenDettached() {
        mLargeScreenShadeHeaderController.simulateViewDetached()
        verify(statusBarIconController).removeIconGroup(any())
    }

    @Test
    fun alphaChangesUpdateVisibility() {
    fun shadeExpandedFraction_updatesAlpha() {
        makeShadeVisible()
        mLargeScreenShadeHeaderController.shadeExpandedFraction = 0f
        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)

        mLargeScreenShadeHeaderController.shadeExpandedFraction = 1f
        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
        mLargeScreenShadeHeaderController.shadeExpandedFraction = 0.5f
        verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
    }

    @Test
@@ -263,54 +263,32 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
    }

    @Test
    fun testShadeExpanded_true_alpha_zero_invisible() {
        view.alpha = 0f
        mLargeScreenShadeHeaderController.largeScreenActive = true
        mLargeScreenShadeHeaderController.qsVisible = true

        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
    }
    fun customizerAnimatorChangesViewVisibility() {
        makeShadeVisible()

    @Test
    fun animatorCallsUpdateVisibilityOnUpdate() {
        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
        val duration = 1000L
        whenever(view.animate()).thenReturn(animator)
        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()

        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, 0L)

        val updateCaptor = argumentCaptor<ValueAnimator.AnimatorUpdateListener>()
        verify(animator).setUpdateListener(capture(updateCaptor))

        mLargeScreenShadeHeaderController.largeScreenActive = true
        mLargeScreenShadeHeaderController.qsVisible = true

        view.alpha = 1f
        updateCaptor.value.onAnimationUpdate(mock())

        assertThat(viewVisibility).isEqualTo(View.VISIBLE)

        view.alpha = 0f
        updateCaptor.value.onAnimationUpdate(mock())

        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, duration)
        verify(animator).setListener(capture(listenerCaptor))
        // Start and end the animation
        listenerCaptor.value.onAnimationStart(mock())
        listenerCaptor.value.onAnimationEnd(mock())
        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
    }

    @Test
    fun animatorListenersClearedAtEnd() {
        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
        whenever(view.animate()).thenReturn(animator)

        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, 0L)
        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
        reset(animator)
        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, duration)
        verify(animator).setListener(capture(listenerCaptor))

        // Start and end the animation
        listenerCaptor.value.onAnimationStart(mock())
        listenerCaptor.value.onAnimationEnd(mock())
        verify(animator).setListener(null)
        verify(animator).setUpdateListener(null)
        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
    }

    @Test
    fun animatorListenersClearedOnCancel() {
    fun animatorListenerClearedAtEnd() {
        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
        whenever(view.animate()).thenReturn(animator)

@@ -318,9 +296,8 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
        verify(animator).setListener(capture(listenerCaptor))

        listenerCaptor.value.onAnimationCancel(mock())
        listenerCaptor.value.onAnimationEnd(mock())
        verify(animator).setListener(null)
        verify(animator).setUpdateListener(null)
    }

    @Test