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

Commit a7298100 authored by Charlie Anderson's avatar Charlie Anderson
Browse files

Fix deadlock in PhysicsAnimatorTestUtils with startForTest()

Bug: 415910933
Flag: EXEMPT test fix
Test: presubmit, TaplTestTaskbarIconDrag#testAppIconDragOnOverviewFromTaskBarToBubbleBar

Change-Id: I4197d39eacb5f42d0da0a3560343494081d86720
parent c8b343c0
Loading
Loading
Loading
Loading
+56 −55
Original line number Diff line number Diff line
@@ -409,46 +409,56 @@ object PhysicsAnimatorTestUtils {
        }

        private fun startForTest() {
            if (Looper.myLooper() == animationThreadHandler.looper) {
                addTestStartListeners(null)
                currentlyRunningStartInternal = true
                animator.startInternal()
                currentlyRunningStartInternal = false
            } else {
                // The testable animator needs to block the main thread until super.start() has been
                // called, since callers expect .start() to be synchronous but we're posting it to a
                // handler here. We may also continue blocking until all animations end, if
                // startBlocksUntilAnimationsEnd = true.
                val unblockLatch = CountDownLatch(if (startBlocksUntilAnimationsEnd) 2 else 1)

                animationThreadHandler.post {
                    // Add an update listener that dispatches to any test update listeners added by
                    // tests.
                animator.addUpdateListener(object : PhysicsAnimator.UpdateListener<T> {
                    override fun onAnimationUpdateForProperty(
                        target: T,
                        values: ArrayMap<FloatPropertyCompat<in T>, PhysicsAnimator.AnimationUpdate>
                    ) {
                    addTestStartListeners(unblockLatch)
                    currentlyRunningStartInternal = true
                    animator.startInternal()
                    currentlyRunningStartInternal = false
                    unblockLatch.countDown()
                }
                unblockLatch.await(timeoutMs, TimeUnit.MILLISECONDS)
            }
        }

        private fun addTestStartListeners(unblockLatch: CountDownLatch?) {
            animator.addUpdateListener { target, values ->
                values.forEach { (property, value) ->
                            allUpdates.getOrPut(property, { ArrayList() }).add(value)
                    allUpdates.getOrPut(property) { ArrayList() }.add(value)
                }

                for (listener in testUpdateListeners) {
                    listener.onAnimationUpdateForProperty(target, values)
                }
            }
                })

            // Add an end listener that dispatches to any test end listeners added by tests, and
            // unblocks the main thread if required.
                animator.addEndListener(object : PhysicsAnimator.EndListener<T> {
                    override fun onAnimationEnd(
                        target: T,
                        property: FloatPropertyCompat<in T>,
                        wasFling: Boolean,
                        canceled: Boolean,
                        finalValue: Float,
                        finalVelocity: Float,
                        allRelevantPropertyAnimsEnded: Boolean
                    ) {
            animator.addEndListener{
               target,
               property,
               wasFling,
               canceled,
               finalValue,
               finalVelocity,
               allRelevantPropertyAnimsEnded ->
                for (listener in testEndListeners) {
                    listener.onAnimationEnd(
                        target, property, wasFling, canceled, finalValue, finalVelocity,
                                    allRelevantPropertyAnimsEnded)
                        allRelevantPropertyAnimsEnded
                    )
                }

                if (allRelevantPropertyAnimsEnded) {
@@ -456,19 +466,10 @@ object PhysicsAnimatorTestUtils {
                    testUpdateListeners.clear()

                    if (startBlocksUntilAnimationsEnd) {
                                unblockLatch.countDown()
                        unblockLatch?.countDown()
                    }
                }
            }
                })

                currentlyRunningStartInternal = true
                animator.startInternal()
                currentlyRunningStartInternal = false
                unblockLatch.countDown()
            }

            unblockLatch.await(timeoutMs, TimeUnit.MILLISECONDS)
        }

        private fun cancelForTest(properties: Set<FloatPropertyCompat<in T>>) {