From 1761ec1b50ec69bd4d3beab62220c49f120de1b1 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Wed, 21 Jun 2023 10:29:29 +0800 Subject: [PATCH] Fix no AVD transfer to client when using setOnExitAnimationListener The reparent transaction of transfer AVD icon to client won't happen when calling VRI#applyTransactionOnDraw during draw section, because that transaction will be deferred into next draw call, and if no extra invalid happen in the view tree, there won't draw another frame. To fix that, call the applyTransactionOnDraw during onPreDraw section, so the transaction can be handled when VRI enter draw section. Bug: 287729934 Test: launch test app which use SplashScreen#setOnExitAnimationListener with a AVD style icon, verify the SurfaceView of AVD can reparent to client's surface hierarchy. Change-Id: I149386543b3449f7e9b98e2f362936a4d2cdd17e --- core/java/android/app/ActivityThread.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 4c90d7b225a5d..41c58ef67e656 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4230,21 +4230,22 @@ public final class ActivityThread extends ClientTransactionHandler decorView.addView(view); view.requestLayout(); - view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() { + view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { private boolean mHandled = false; @Override - public void onDraw() { + public boolean onPreDraw() { if (mHandled) { - return; + return true; } mHandled = true; // Transfer the splash screen view from shell to client. - // Call syncTransferSplashscreenViewTransaction at the first onDraw so we can ensure - // the client view is ready to show and we can use applyTransactionOnDraw to make - // all transitions happen at the same frame. + // Call syncTransferSplashscreenViewTransaction at the first onPreDraw, so we can + // ensure the client view is ready to show, and can use applyTransactionOnDraw to + // make all transitions happen at the same frame. syncTransferSplashscreenViewTransaction( view, r.token, decorView, startingWindowLeash); - view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this)); + view.post(() -> view.getViewTreeObserver().removeOnPreDrawListener(this)); + return true; } }); }