Merge "Fix performance regressions" into tm-qpr-dev am: e8b7907312
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21422787 Change-Id: Ie1cdcb55ac0dbed9f17c3d682d84fbb57b245161 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package com.android.systemui.shade
|
package com.android.systemui.shade
|
||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
|
import android.animation.AnimatorListenerAdapter
|
||||||
import android.annotation.IdRes
|
import android.annotation.IdRes
|
||||||
import android.app.StatusBarManager
|
import android.app.StatusBarManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
@@ -145,6 +146,14 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
|||||||
updateListeners()
|
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
|
* 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.
|
* Lockscreen, as the shade is visible but QS is not.
|
||||||
@@ -176,14 +185,9 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
var shadeExpandedFraction = -1f
|
var shadeExpandedFraction = -1f
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (qsVisible && field != value) {
|
||||||
val oldAlpha = header.alpha
|
|
||||||
header.alpha = ShadeInterpolation.getContentAlpha(value)
|
header.alpha = ShadeInterpolation.getContentAlpha(value)
|
||||||
field = 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)
|
dumpManager.registerDumpable(this)
|
||||||
configurationController.addCallback(configurationControllerListener)
|
configurationController.addCallback(configurationControllerListener)
|
||||||
demoModeController.addCallback(demoModeReceiver)
|
demoModeController.addCallback(demoModeReceiver)
|
||||||
|
statusBarIconController.addIconGroup(iconManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewDetached() {
|
override fun onViewDetached() {
|
||||||
@@ -325,6 +330,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
|||||||
dumpManager.unregisterDumpable(this::class.java.simpleName)
|
dumpManager.unregisterDumpable(this::class.java.simpleName)
|
||||||
configurationController.removeCallback(configurationControllerListener)
|
configurationController.removeCallback(configurationControllerListener)
|
||||||
demoModeController.removeCallback(demoModeReceiver)
|
demoModeController.removeCallback(demoModeReceiver)
|
||||||
|
statusBarIconController.removeIconGroup(iconManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disable(state1: Int, state2: Int, animate: Boolean) {
|
fun disable(state1: Int, state2: Int, animate: Boolean) {
|
||||||
@@ -339,31 +345,10 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
|||||||
.setDuration(duration)
|
.setDuration(duration)
|
||||||
.alpha(if (show) 0f else 1f)
|
.alpha(if (show) 0f else 1f)
|
||||||
.setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
|
.setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
|
||||||
.setUpdateListener {
|
.setListener(CustomizerAnimationListener(show))
|
||||||
updateVisibility()
|
|
||||||
}
|
|
||||||
.setListener(endAnimationListener)
|
|
||||||
.start()
|
.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() {
|
private fun loadConstraints() {
|
||||||
if (header is MotionLayout) {
|
if (header is MotionLayout) {
|
||||||
// Use resources.getXml instead of passing the resource id due to bug b/205018300
|
// 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() {
|
private fun updateVisibility() {
|
||||||
val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
|
val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
|
||||||
View.GONE
|
View.GONE
|
||||||
} else if (qsVisible && header.alpha > 0f) {
|
} else if (qsVisible && !customizing) {
|
||||||
View.VISIBLE
|
View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
View.INVISIBLE
|
View.INVISIBLE
|
||||||
@@ -502,10 +487,8 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
|||||||
if (visible) {
|
if (visible) {
|
||||||
updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
|
updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
|
||||||
qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
|
qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
|
||||||
statusBarIconController.addIconGroup(iconManager)
|
|
||||||
} else {
|
} else {
|
||||||
qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
|
qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
|
||||||
statusBarIconController.removeIconGroup(iconManager)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,4 +561,23 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
internal fun simulateViewDetached() = this.onViewDetached()
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.android.systemui.shade
|
package com.android.systemui.shade
|
||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.app.StatusBarManager
|
import android.app.StatusBarManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
@@ -44,6 +43,7 @@ import org.mockito.ArgumentMatchers.anyFloat
|
|||||||
import org.mockito.ArgumentMatchers.anyInt
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito.mock
|
||||||
|
import org.mockito.Mockito.reset
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.verifyZeroInteractions
|
import org.mockito.Mockito.verifyZeroInteractions
|
||||||
import org.mockito.junit.MockitoJUnit
|
import org.mockito.junit.MockitoJUnit
|
||||||
@@ -158,9 +158,19 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
|||||||
fun updateListeners_registersWhenVisible() {
|
fun updateListeners_registersWhenVisible() {
|
||||||
makeShadeVisible()
|
makeShadeVisible()
|
||||||
verify(qsCarrierGroupController).setListening(true)
|
verify(qsCarrierGroupController).setListening(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun statusIconsAddedWhenAttached() {
|
||||||
verify(statusBarIconController).addIconGroup(any())
|
verify(statusBarIconController).addIconGroup(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun statusIconsRemovedWhenDettached() {
|
||||||
|
mLargeScreenShadeHeaderController.simulateViewDetached()
|
||||||
|
verify(statusBarIconController).removeIconGroup(any())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun shadeExpandedFraction_updatesAlpha() {
|
fun shadeExpandedFraction_updatesAlpha() {
|
||||||
makeShadeVisible()
|
makeShadeVisible()
|
||||||
@@ -168,16 +178,6 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
|||||||
verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
|
verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun alphaChangesUpdateVisibility() {
|
|
||||||
makeShadeVisible()
|
|
||||||
mLargeScreenShadeHeaderController.shadeExpandedFraction = 0f
|
|
||||||
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
|
|
||||||
|
|
||||||
mLargeScreenShadeHeaderController.shadeExpandedFraction = 1f
|
|
||||||
assertThat(viewVisibility).isEqualTo(View.VISIBLE)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleCarrier_enablesCarrierIconsInStatusIcons() {
|
fun singleCarrier_enablesCarrierIconsInStatusIcons() {
|
||||||
whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
|
whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
|
||||||
@@ -263,40 +263,32 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testShadeExpanded_true_alpha_zero_invisible() {
|
fun customizerAnimatorChangesViewVisibility() {
|
||||||
view.alpha = 0f
|
makeShadeVisible()
|
||||||
mLargeScreenShadeHeaderController.largeScreenActive = true
|
|
||||||
mLargeScreenShadeHeaderController.qsVisible = true
|
|
||||||
|
|
||||||
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun animatorCallsUpdateVisibilityOnUpdate() {
|
|
||||||
val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
|
val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
|
||||||
|
val duration = 1000L
|
||||||
whenever(view.animate()).thenReturn(animator)
|
whenever(view.animate()).thenReturn(animator)
|
||||||
|
val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
|
||||||
|
|
||||||
mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, 0L)
|
mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, duration)
|
||||||
|
verify(animator).setListener(capture(listenerCaptor))
|
||||||
val updateCaptor = argumentCaptor<ValueAnimator.AnimatorUpdateListener>()
|
// Start and end the animation
|
||||||
verify(animator).setUpdateListener(capture(updateCaptor))
|
listenerCaptor.value.onAnimationStart(mock())
|
||||||
|
listenerCaptor.value.onAnimationEnd(mock())
|
||||||
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())
|
|
||||||
|
|
||||||
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
|
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
|
||||||
|
|
||||||
|
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())
|
||||||
|
assertThat(viewVisibility).isEqualTo(View.VISIBLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun animatorListenersClearedAtEnd() {
|
fun animatorListenerClearedAtEnd() {
|
||||||
val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
|
val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
|
||||||
whenever(view.animate()).thenReturn(animator)
|
whenever(view.animate()).thenReturn(animator)
|
||||||
|
|
||||||
@@ -306,21 +298,6 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
listenerCaptor.value.onAnimationEnd(mock())
|
listenerCaptor.value.onAnimationEnd(mock())
|
||||||
verify(animator).setListener(null)
|
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
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user