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 fadeInInterpolator the interpolator to use when fading in the view. Unused if
* [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
fun animateAddition(
@@ -174,7 +176,8 @@ class ViewHierarchyAnimator {
duration: Long = DEFAULT_DURATION,
includeMargins: Boolean = false,
includeFadeIn: Boolean = false,
fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR
fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR,
onAnimationEnd: Runnable? = null,
): Boolean {
if (
occupiesSpace(
@@ -193,7 +196,8 @@ class ViewHierarchyAnimator {
origin,
interpolator,
duration,
ignorePreviousValues = !includeMargins
ignorePreviousValues = !includeMargins,
onAnimationEnd,
)
addListener(rootView, listener, recursive = true)
@@ -246,14 +250,16 @@ class ViewHierarchyAnimator {
origin: Hotspot,
interpolator: Interpolator,
duration: Long,
ignorePreviousValues: Boolean
ignorePreviousValues: Boolean,
onAnimationEnd: Runnable? = null,
): View.OnLayoutChangeListener {
return createListener(
interpolator,
duration,
ephemeral = true,
origin = origin,
ignorePreviousValues = ignorePreviousValues
ignorePreviousValues = ignorePreviousValues,
onAnimationEnd,
)
}
@@ -272,7 +278,8 @@ class ViewHierarchyAnimator {
duration: Long,
ephemeral: Boolean,
origin: Hotspot? = null,
ignorePreviousValues: Boolean = false
ignorePreviousValues: Boolean = false,
onAnimationEnd: Runnable? = null,
): View.OnLayoutChangeListener {
return object : View.OnLayoutChangeListener {
override fun onLayoutChange(
@@ -340,7 +347,8 @@ class ViewHierarchyAnimator {
endValues,
interpolator,
duration,
ephemeral
ephemeral,
onAnimationEnd,
)
}
}
@@ -903,7 +911,8 @@ class ViewHierarchyAnimator {
endValues: Map<Bound, Int>,
interpolator: Interpolator,
duration: Long,
ephemeral: Boolean
ephemeral: Boolean,
onAnimationEnd: Runnable? = null,
) {
val propertyValuesHolders =
buildList {
@@ -941,6 +950,9 @@ class ViewHierarchyAnimator {
// listener.
recursivelyRemoveListener(view)
}
if (!cancelled) {
onAnimationEnd?.run()
}
}
override fun onAnimationCancel(animation: Animator?) {

View File

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

View File

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

View File

@@ -663,6 +663,60 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
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
fun animatesViewRemovalFromStartToEnd() {
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) {
(rootView.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.end()