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

Commit 63cf4d07 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Updating SurfaceTransactionApplier to handle view not being attached

Bug: 278833389
Test: Presubmit
Flag: N/A
Change-Id: I88c240a1a7bdfe2e68c858c30e91cc5d06bc7bcf
parent 2e17bcaa
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -2114,12 +2114,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
    }

    protected void linkRecentsViewScroll() {
        SurfaceTransactionApplier.create(mRecentsView, applier -> {
        SurfaceTransactionApplier applier = new SurfaceTransactionApplier(mRecentsView);
        runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
                        .setSyncTransactionApplier(applier));
        runOnRecentsAnimationAndLauncherBound(() ->
                mRecentsAnimationTargets.addReleaseCheck(applier));
        });

        mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener);
        runOnRecentsAnimationAndLauncherBound(() ->
+34 −36
Original line number Diff line number Diff line
@@ -22,13 +22,11 @@ import android.os.Message;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewRootImpl;

import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;

import java.util.function.Consumer;


/**
 * Helper class to apply surface transactions in sync with RenderThread similar to
 *   android.view.SyncRtSurfaceTransactionApplier
@@ -39,22 +37,47 @@ public class SurfaceTransactionApplier extends ReleaseCheck {

    private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;

    private final SurfaceControl mBarrierSurfaceControl;
    private final ViewRootImpl mTargetViewRootImpl;
    private final Handler mApplyHandler;

    private boolean mInitialized;
    private SurfaceControl mBarrierSurfaceControl;
    private ViewRootImpl mTargetViewRootImpl;

    private int mLastSequenceNumber = 0;

    /**
     * @param targetView The view in the surface that acts as synchronization anchor.
     */
    public SurfaceTransactionApplier(View targetView) {
        mTargetViewRootImpl = targetView.getViewRootImpl();
        mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
        if (targetView.isAttachedToWindow()) {
            initialize(targetView);
        } else {
            mInitialized = false;
            targetView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
                @Override
                public void onViewAttachedToWindow(View v) {
                    if (!mInitialized) {
                        targetView.removeOnAttachStateChangeListener(this);
                        initialize(targetView);
                    }
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                    // Do nothing
                }
            });
        }
        mApplyHandler = new Handler(this::onApplyMessage);
        setCanRelease(true);
    }

    private void initialize(View view) {
        mTargetViewRootImpl = view.getViewRootImpl();
        mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
        mInitialized = true;
    }

    protected boolean onApplyMessage(Message msg) {
        if (msg.what == MSG_UPDATE_SEQUENCE_NUMBER) {
            setCanRelease(msg.arg1 == mLastSequenceNumber);
@@ -70,6 +93,10 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
     *               this method to avoid synchronization issues.
     */
    public void scheduleApply(SurfaceTransaction params) {
        if (!mInitialized) {
            params.getTransaction().apply();
            return;
        }
        View view = mTargetViewRootImpl.getView();
        if (view == null) {
            return;
@@ -93,33 +120,4 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
        // Make sure a frame gets scheduled.
        view.invalidate();
    }

    /**
     * Creates an instance of SurfaceTransactionApplier, deferring until the target view is
     * attached if necessary.
     */
    public static void create(
            final View targetView, final Consumer<SurfaceTransactionApplier> callback) {
        if (targetView == null) {
            // No target view, no applier
            callback.accept(null);
        } else if (targetView.isAttachedToWindow()) {
            // Already attached, we're good to go
            callback.accept(new SurfaceTransactionApplier(targetView));
        } else {
            // Haven't been attached before we can get the view root
            targetView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                @Override
                public void onViewAttachedToWindow(View v) {
                    targetView.removeOnAttachStateChangeListener(this);
                    callback.accept(new SurfaceTransactionApplier(targetView));
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                    // Do nothing
                }
            });
        }
    }
}