Merge "[Media TTT] Only request accessibility focus if our animation ends successfully." into tm-qpr-dev

This commit is contained in:
Caitlin Shkuratov
2022-08-18 18:51:42 +00:00
committed by Android (Google) Code Review
4 changed files with 86 additions and 14 deletions

View File

@@ -165,6 +165,8 @@ class ViewHierarchyAnimator {
* @param includeFadeIn true if the animator should also fade in the view and child views. * @param includeFadeIn true if the animator should also fade in the view and child views.
* @param fadeInInterpolator the interpolator to use when fading in the view. Unused if * @param fadeInInterpolator the interpolator to use when fading in the view. Unused if
* [includeFadeIn] is false. * [includeFadeIn] is false.
* @param onAnimationEnd an optional runnable that will be run once the animation
* finishes successfully. Will not be run if the animation is cancelled.
*/ */
@JvmOverloads @JvmOverloads
fun animateAddition( fun animateAddition(
@@ -174,7 +176,8 @@ class ViewHierarchyAnimator {
duration: Long = DEFAULT_DURATION, duration: Long = DEFAULT_DURATION,
includeMargins: Boolean = false, includeMargins: Boolean = false,
includeFadeIn: Boolean = false, includeFadeIn: Boolean = false,
fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR,
onAnimationEnd: Runnable? = null,
): Boolean { ): Boolean {
if ( if (
occupiesSpace( occupiesSpace(
@@ -193,7 +196,8 @@ class ViewHierarchyAnimator {
origin, origin,
interpolator, interpolator,
duration, duration,
ignorePreviousValues = !includeMargins ignorePreviousValues = !includeMargins,
onAnimationEnd,
) )
addListener(rootView, listener, recursive = true) addListener(rootView, listener, recursive = true)
@@ -246,14 +250,16 @@ class ViewHierarchyAnimator {
origin: Hotspot, origin: Hotspot,
interpolator: Interpolator, interpolator: Interpolator,
duration: Long, duration: Long,
ignorePreviousValues: Boolean ignorePreviousValues: Boolean,
onAnimationEnd: Runnable? = null,
): View.OnLayoutChangeListener { ): View.OnLayoutChangeListener {
return createListener( return createListener(
interpolator, interpolator,
duration, duration,
ephemeral = true, ephemeral = true,
origin = origin, origin = origin,
ignorePreviousValues = ignorePreviousValues ignorePreviousValues = ignorePreviousValues,
onAnimationEnd,
) )
} }
@@ -272,7 +278,8 @@ class ViewHierarchyAnimator {
duration: Long, duration: Long,
ephemeral: Boolean, ephemeral: Boolean,
origin: Hotspot? = null, origin: Hotspot? = null,
ignorePreviousValues: Boolean = false ignorePreviousValues: Boolean = false,
onAnimationEnd: Runnable? = null,
): View.OnLayoutChangeListener { ): View.OnLayoutChangeListener {
return object : View.OnLayoutChangeListener { return object : View.OnLayoutChangeListener {
override fun onLayoutChange( override fun onLayoutChange(
@@ -340,7 +347,8 @@ class ViewHierarchyAnimator {
endValues, endValues,
interpolator, interpolator,
duration, duration,
ephemeral ephemeral,
onAnimationEnd,
) )
} }
} }
@@ -903,7 +911,8 @@ class ViewHierarchyAnimator {
endValues: Map<Bound, Int>, endValues: Map<Bound, Int>,
interpolator: Interpolator, interpolator: Interpolator,
duration: Long, duration: Long,
ephemeral: Boolean ephemeral: Boolean,
onAnimationEnd: Runnable? = null,
) { ) {
val propertyValuesHolders = val propertyValuesHolders =
buildList { buildList {
@@ -941,6 +950,9 @@ class ViewHierarchyAnimator {
// listener. // listener.
recursivelyRemoveListener(view) recursivelyRemoveListener(view)
} }
if (!cancelled) {
onAnimationEnd?.run()
}
} }
override fun onAnimationCancel(animation: Animator?) { override fun onAnimationCancel(animation: Animator?) {

View File

@@ -56,7 +56,7 @@ abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>(
internal val logger: MediaTttLogger, internal val logger: MediaTttLogger,
internal val windowManager: WindowManager, internal val windowManager: WindowManager,
private val viewUtil: ViewUtil, private val viewUtil: ViewUtil,
@Main internal val mainExecutor: DelayableExecutor, @Main private val mainExecutor: DelayableExecutor,
private val accessibilityManager: AccessibilityManager, private val accessibilityManager: AccessibilityManager,
private val configurationController: ConfigurationController, private val configurationController: ConfigurationController,
private val powerManager: PowerManager, private val powerManager: PowerManager,

View File

@@ -160,12 +160,8 @@ class MediaTttChipControllerSender @Inject constructor(
duration = ANIMATION_DURATION, duration = ANIMATION_DURATION,
includeMargins = true, includeMargins = true,
includeFadeIn = true, includeFadeIn = true,
) // We can only request focus once the animation finishes.
onAnimationEnd = { chipInnerView.requestAccessibilityFocus() },
// We can only request focus once the animation finishes.
mainExecutor.executeDelayed(
{ chipInnerView.requestAccessibilityFocus() },
ANIMATION_DURATION
) )
} }

View File

@@ -663,6 +663,60 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
assertEquals(0.5f, secondChild.alpha) assertEquals(0.5f, secondChild.alpha)
} }
@Test
fun animateAddition_runnableRunsWhenAnimationEnds() {
var runnableRun = false
val onAnimationEndRunnable = { runnableRun = true }
ViewHierarchyAnimator.animateAddition(
rootView,
origin = ViewHierarchyAnimator.Hotspot.CENTER,
includeMargins = true,
onAnimationEnd = onAnimationEndRunnable
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
endAnimation(rootView)
assertEquals(true, runnableRun)
}
@Test
fun animateAddition_runnableDoesNotRunWhenAnimationCancelled() {
var runnableRun = false
val onAnimationEndRunnable = { runnableRun = true }
ViewHierarchyAnimator.animateAddition(
rootView,
origin = ViewHierarchyAnimator.Hotspot.CENTER,
includeMargins = true,
onAnimationEnd = onAnimationEndRunnable
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
cancelAnimation(rootView)
assertEquals(false, runnableRun)
}
@Test
fun animationAddition_runnableDoesNotRunWhenOnlyPartwayThroughAnimation() {
var runnableRun = false
val onAnimationEndRunnable = { runnableRun = true }
ViewHierarchyAnimator.animateAddition(
rootView,
origin = ViewHierarchyAnimator.Hotspot.CENTER,
includeMargins = true,
onAnimationEnd = onAnimationEndRunnable
)
rootView.layout(50 /* l */, 50 /* t */, 100 /* r */, 100 /* b */)
advanceAnimation(rootView, 0.5f)
assertEquals(false, runnableRun)
}
@Test @Test
fun animatesViewRemovalFromStartToEnd() { fun animatesViewRemovalFromStartToEnd() {
setUpRootWithChildren() setUpRootWithChildren()
@@ -1158,6 +1212,16 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
} }
} }
private fun cancelAnimation(rootView: View) {
(rootView.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
if (rootView is ViewGroup) {
for (i in 0 until rootView.childCount) {
cancelAnimation(rootView.getChildAt(i))
}
}
}
private fun endFadeInAnimation(rootView: View) { private fun endFadeInAnimation(rootView: View) {
(rootView.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.end() (rootView.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.end()