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

Commit 99d0b778 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add a 100ms timeout when waiting for animation finish." into main

parents 78d1bc52 efee0571
Loading
Loading
Loading
Loading
+41 −9
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.wm.shell.shared.TransitionUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * An implementation of {@link IRemoteTransition} that accepts a {@link UIComponent} as the origin
@@ -52,6 +53,7 @@ import java.util.List;
 */
public class OriginRemoteTransition extends IRemoteTransition.Stub {
    private static final String TAG = "OriginRemoteTransition";
    private static final long FINISH_ANIMATION_TIMEOUT_MS = 100;

    private final Context mContext;
    private final boolean mIsEntry;
@@ -248,14 +250,12 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {

        if (mIsEntry) {
            if (!closingSurfaces.isEmpty()) {
                tmpTransaction
                        .setRelativeLayer(mOriginLeash, closingSurfaces.get(0), 1);
                tmpTransaction.setRelativeLayer(mOriginLeash, closingSurfaces.get(0), 1);
            } else {
                logW("Missing closing surface is entry transition");
            }
            if (!openingSurfaces.isEmpty()) {
                tmpTransaction
                        .setRelativeLayer(
                tmpTransaction.setRelativeLayer(
                        openingSurfaces.get(openingSurfaces.size() - 1), mOriginLeash, 1);
            } else {
                logW("Missing opening surface is entry transition");
@@ -263,8 +263,7 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {

        } else {
            if (!openingSurfaces.isEmpty()) {
                tmpTransaction
                        .setRelativeLayer(mOriginLeash, openingSurfaces.get(0), 1);
                tmpTransaction.setRelativeLayer(mOriginLeash, openingSurfaces.get(0), 1);
            } else {
                logW("Missing opening surface is exit transition");
            }
@@ -293,12 +292,26 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {

    private void finishAnimation(boolean finished) {
        logD("finishAnimation: finished=" + finished);
        OneShotRunnable finishInternalRunnable = new OneShotRunnable(this::finishInternal);
        Runnable timeoutRunnable =
                () -> {
                    Log.w(TAG, "Timeout waiting for surface transaction!");
                    finishInternalRunnable.run();
                };
        Runnable committedRunnable =
                () -> {
                    // Remove the timeout runnable.
                    mHandler.removeCallbacks(timeoutRunnable);
                    finishInternalRunnable.run();
                };
        if (mAnimator == null) {
            // The transition didn't start. Ensure we apply the start transaction and report
            // finish afterwards.
            mStartTransaction
                    .addTransactionCommittedListener(mHandler::post, this::finishInternal)
                    .addTransactionCommittedListener(mHandler::post, committedRunnable::run)
                    .apply();
            // Call finishInternal() anyway after the timeout.
            mHandler.postDelayed(timeoutRunnable, FINISH_ANIMATION_TIMEOUT_MS);
            return;
        }
        mAnimator = null;
@@ -306,8 +319,10 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {
        mPlayer.onEnd(finished);
        // Detach the origin from the transition leash and report finish after it's done.
        mOriginTransaction
                .detachFromTransitionLeash(mOrigin, mHandler::post, this::finishInternal)
                .detachFromTransitionLeash(mOrigin, mHandler::post, committedRunnable)
                .commit();
        // Call finishInternal() anyway after the timeout.
        mHandler.postDelayed(timeoutRunnable, FINISH_ANIMATION_TIMEOUT_MS);
    }

    private void finishInternal() {
@@ -423,6 +438,23 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub {
        return out;
    }

    /** A {@link Runnable} that will only run once. */
    private static class OneShotRunnable implements Runnable {
        private final AtomicBoolean mDone = new AtomicBoolean();
        private final Runnable mRunnable;

        OneShotRunnable(Runnable runnable) {
            this.mRunnable = runnable;
        }

        @Override
        public void run() {
            if (!mDone.getAndSet(true)) {
                mRunnable.run();
            }
        }
    }

    /**
     * An interface that represents an origin transitions.
     *
+11 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver.OnDrawListener;

import java.util.ArrayList;
@@ -131,7 +132,6 @@ public class ViewUIComponent implements UIComponent {
        mView.getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
        // Restore view visibility
        mView.setVisibility(mVisibleOverride ? View.VISIBLE : View.INVISIBLE);
        mView.invalidate();
        // Clean up surfaces.
        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        t.reparent(sc, null)
@@ -142,8 +142,16 @@ public class ViewUIComponent implements UIComponent {
                            sc.release();
                            executor.execute(onDone);
                        });
        ViewRootImpl viewRoot = mView.getViewRootImpl();
        if (viewRoot == null) {
            t.apply();
        } else {
            // Apply transaction AFTER the view is drawn.
        mView.getRootSurfaceControl().applyTransactionOnDraw(t);
            viewRoot.applyTransactionOnDraw(t);
            // Request layout to force redrawing the entire view tree, so that the transaction is
            // guaranteed to be applied.
            viewRoot.requestLayout();
        }
    }

    @Override