Updating SurfaceTransactionApplier to handle view not being attached
Bug: 278833389
Test: Presubmit
Flag: N/A
Change-Id: I88c240a1a7bdfe2e68c858c30e91cc5d06bc7bcf
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 5333cbe..7d47945 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -2114,12 +2114,11 @@
}
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 95473dc..bb028a7 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.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 @@
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 @@
* 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 @@
// 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
- }
- });
- }
- }
}