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

Commit c7a46da4 authored by Arthur Hung's avatar Arthur Hung
Browse files

Prevent waiting when inject event without animation

Synchronously inject input event would wait for animations complete,
but if no surface animation is on going and 'scheduleAnimation' is
called in order to apply the pending transaction. It would wait
until timeout(=5s) because no 'notify' would be called from
framecallback. That would cause timeout problem when emulate swipe
gesture via inject many events.

This would provide a flag in WindowAnimator to ensure the pending
transaction could be applied and exit waiting if there is no
other animation.

Bug: 150250453
Bug: 152478735
Bug: 152462354
Test: atest libinput_tests inputflinger_tests
Test: atest --rerun-until-failure 100 WindowFocusTests#testMovingDisplayToTopByKeyEvent
Test: atest MemoryTests#testActivityRecreation
Test: Tests have inject events.

Change-Id: If1db5c4d923ddbcfcd6eb3db38a41fee70913568
parent 8874a961
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ public class WindowAnimator {
     * vsync-app and then schedule the animation tick at the right time (vsync-sf).
     */
    private boolean mAnimationFrameCallbackScheduled;
    boolean mNotifyWhenNoAnimation = false;

    /**
     * A list of runnable that need to be run after {@link WindowContainer#prepareSurfaces} is
@@ -97,6 +98,9 @@ public class WindowAnimator {
            synchronized (mService.mGlobalLock) {
                mAnimationFrameCallbackScheduled = false;
                animate(frameTimeNs);
                if (mNotifyWhenNoAnimation && !mLastRootAnimating) {
                    mService.mGlobalLock.notifyAll();
                }
            }
        };
    }
+11 −3
Original line number Diff line number Diff line
@@ -193,7 +193,6 @@ import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MergedConfiguration;
import android.util.Slog;
import android.util.SparseArray;
@@ -7746,9 +7745,16 @@ public class WindowManagerService extends IWindowManager.Stub
        t.syncInputWindows().apply();
    }

    /**
     * Wait until all container animations and surface operations behalf of WindowManagerService
     * complete.
     */
    private void waitForAnimationsToComplete() {
        synchronized (mGlobalLock) {
            long timeoutRemaining = ANIMATION_COMPLETED_TIMEOUT_MS;
            // This could prevent if there is no container animation, we still have to apply the
            // pending transaction and exit waiting.
            mAnimator.mNotifyWhenNoAnimation = true;
            while ((mAnimator.isAnimationScheduled()
                    || mRoot.isAnimating(TRANSITION | CHILDREN)) && timeoutRemaining > 0) {
                long startTime = System.currentTimeMillis();
@@ -7758,9 +7764,11 @@ public class WindowManagerService extends IWindowManager.Stub
                }
                timeoutRemaining -= (System.currentTimeMillis() - startTime);
            }
            mAnimator.mNotifyWhenNoAnimation = false;

            if (mRoot.isAnimating(TRANSITION | CHILDREN)) {
                Log.w(TAG, "Timed out waiting for animations to complete.");
            if (mAnimator.isAnimationScheduled()
                    || mRoot.isAnimating(TRANSITION | CHILDREN)) {
                Slog.w(TAG, "Timed out waiting for animations to complete.");
            }
        }
    }