From 63cf4d07a824bb1b21ae6134c53f4fe79919c54e Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 5 May 2023 15:56:39 -0700 Subject: [PATCH] Updating SurfaceTransactionApplier to handle view not being attached Bug: 278833389 Test: Presubmit Flag: N/A Change-Id: I88c240a1a7bdfe2e68c858c30e91cc5d06bc7bcf --- .../android/quickstep/AbsSwipeUpHandler.java | 11 ++- .../util/SurfaceTransactionApplier.java | 70 +++++++++---------- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 5333cbe919..7d47945fc4 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -2114,12 +2114,11 @@ public abstract class AbsSwipeUpHandler, } protected void linkRecentsViewScroll() { - SurfaceTransactionApplier.create(mRecentsView, applier -> { - runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams() - .setSyncTransactionApplier(applier)); - runOnRecentsAnimationAndLauncherBound(() -> - mRecentsAnimationTargets.addReleaseCheck(applier)); - }); + SurfaceTransactionApplier applier = new SurfaceTransactionApplier(mRecentsView); + runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams() + .setSyncTransactionApplier(applier)); + runOnRecentsAnimationAndLauncherBound(() -> + mRecentsAnimationTargets.addReleaseCheck(applier)); mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener); runOnRecentsAnimationAndLauncherBound(() -> diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java index 95473dc39a..bb028a700c 100644 --- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java +++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java @@ -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 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 - } - }); - } - } }