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

Commit cb8d2c79 authored by Charlie Anderson's avatar Charlie Anderson Committed by Android (Google) Code Review
Browse files

Merge "Fix deadlock in PhysicsAnimatorTestUtils with startForTest()" into main

parents 9dd52325 a7298100
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>>) {