Clear listeners after animation

Also, only call `updateVisibility` when the alpha changes between
non-zero and zero

Test: atest LargeScreenShadeHeaderControllerTest
Bug: 265104777
Change-Id: Ie108ba84608a8c54322df0900b0d11d5a63f87e1
This commit is contained in:
Fabian Kozynski
2023-01-24 10:58:15 -05:00
parent a96800911c
commit 0fae7128d4
2 changed files with 55 additions and 3 deletions

View File

@@ -16,6 +16,7 @@
package com.android.systemui.shade
import android.animation.Animator
import android.annotation.IdRes
import android.app.StatusBarManager
import android.content.res.Configuration
@@ -45,7 +46,6 @@ import com.android.systemui.qs.HeaderPrivacyIconsController
import com.android.systemui.qs.carrier.QSCarrierGroup
import com.android.systemui.qs.carrier.QSCarrierGroupController
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
@@ -176,9 +176,13 @@ class LargeScreenShadeHeaderController @Inject constructor(
var shadeExpandedFraction = -1f
set(value) {
if (field != value) {
val oldAlpha = header.alpha
header.alpha = ShadeInterpolation.getContentAlpha(value)
field = value
updateVisibility()
if ((oldAlpha == 0f && header.alpha > 0f) ||
(oldAlpha > 0f && header.alpha == 0f)) {
updateVisibility()
}
}
}
@@ -335,9 +339,28 @@ class LargeScreenShadeHeaderController @Inject constructor(
.setUpdateListener {
updateVisibility()
}
.setListener(endAnimationListener)
.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

View File

@@ -1,5 +1,6 @@
package com.android.systemui.shade
import android.animation.Animator
import android.animation.ValueAnimator
import android.app.StatusBarManager
import android.content.Context
@@ -45,8 +46,8 @@ import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -292,6 +293,34 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
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>()
verify(animator).setListener(capture(listenerCaptor))
listenerCaptor.value.onAnimationEnd(mock())
verify(animator).setListener(null)
verify(animator).setUpdateListener(null)
}
@Test
fun animatorListenersClearedOnCancel() {
val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
whenever(view.animate()).thenReturn(animator)
mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, 0L)
val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
verify(animator).setListener(capture(listenerCaptor))
listenerCaptor.value.onAnimationCancel(mock())
verify(animator).setListener(null)
verify(animator).setUpdateListener(null)
}
@Test
fun demoMode_attachDemoMode() {
val cb = argumentCaptor<DemoMode>()