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

Commit ad010b08 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Sync input transaction for startActivitySync

The method should be only used for tests. The tests usually expect
a stable state to proceed next step after the method returns.

By using syncInputTransactions(waitForAnimations=true), it can cover
both the purpose of [1] and [2].

[1]: Ifd7bfd41b39518518f4013fad80c3acd1e8b2354
[2]: I5457ab67ac574530dc1aa84549ca11e7e3f0d714

The original mEnterAnimationComplete is unable to handle trampoline
activities, i.e. the target activity launches another activity
in its onCreate. Then the target activity may not receive animation
complete or its onStop will clear the animation complete state, and
waitForEnterAnimationComplete doesn't know what's the next activity
to wait for. That always leads to a 5s timeout.

While syncInputTransactions can wait for global transition, so it can
return once the entire consecutive launch sequence is done.

Bug: 330043325
Flag: TEST_ONLY
Test: atest CtsWindowManagerDeviceActivity:ActivityLifecycleTests
Change-Id: Iea1e2840bbcb8dcde1a80340c4ae42e26ebf009a
parent f7c4dc87
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -1027,9 +1027,6 @@ public class Activity extends ContextThemeWrapper
    /** The autofill client controller. Always access via {@link #getAutofillClientController()}. */
    private AutofillClientController mAutofillClientController;

    /** @hide */
    boolean mEnterAnimationComplete;

    private boolean mIsInMultiWindowMode;
    /** @hide */
    boolean mIsInPictureInPictureMode;
@@ -2898,7 +2895,6 @@ public class Activity extends ContextThemeWrapper
        mCalled = true;

        getAutofillClientController().onActivityStopped(mIntent, mChangingConfigurations);
        mEnterAnimationComplete = false;

        notifyVoiceInteractionManagerServiceActivityEvent(
                VoiceInteractionSession.VOICE_INTERACTION_ACTIVITY_EVENT_STOP);
@@ -8589,8 +8585,6 @@ public class Activity extends ContextThemeWrapper
     * @hide
     */
    public void dispatchEnterAnimationComplete() {
        mEnterAnimationComplete = true;
        mInstrumentation.onEnterAnimationComplete();
        onEnterAnimationComplete();
        if (getWindow() != null && getWindow().getDecorView() != null) {
            View decorView = getWindow().getDecorView();
+8 −34
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManagerGlobal;
@@ -137,7 +136,6 @@ public class Instrumentation {
    private PerformanceCollector mPerformanceCollector;
    private Bundle mPerfMetrics = new Bundle();
    private UiAutomation mUiAutomation;
    private final Object mAnimationCompleteLock = new Object();

    @RavenwoodKeep
    public Instrumentation() {
@@ -455,31 +453,6 @@ public class Instrumentation {
        idler.waitForIdle();
    }

    private void waitForEnterAnimationComplete(Activity activity) {
        synchronized (mAnimationCompleteLock) {
            long timeout = 5000;
            try {
                // We need to check that this specified Activity completed the animation, not just
                // any Activity. If it was another Activity, then decrease the timeout by how long
                // it's already waited and wait for the thread to wakeup again.
                while (timeout > 0 && !activity.mEnterAnimationComplete) {
                    long startTime = System.currentTimeMillis();
                    mAnimationCompleteLock.wait(timeout);
                    long totalTime = System.currentTimeMillis() - startTime;
                    timeout -= totalTime;
                }
            } catch (InterruptedException e) {
            }
        }
    }

    /** @hide */
    public void onEnterAnimationComplete() {
        synchronized (mAnimationCompleteLock) {
            mAnimationCompleteLock.notifyAll();
        }
    }

    /**
     * Execute a call on the application's main thread, blocking until it is
     * complete.  Useful for doing things that are not thread-safe, such as
@@ -640,13 +613,14 @@ public class Instrumentation {
            activity = aw.activity;
        }

        // Do not call this method within mSync, lest it could block the main thread.
        waitForEnterAnimationComplete(activity);

        // Apply an empty transaction to ensure SF has a chance to update before
        // the Activity is ready (b/138263890).
        try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
            t.apply(true);
        // Typically, callers expect that the launched activity can receive input events after this
        // method returns, so wait until a stable state, i.e. animation is finished and input info
        // is updated.
        try {
            WindowManagerGlobal.getWindowManagerService()
                    .syncInputTransactions(true /* waitForAnimations */);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return activity;
    }