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
This commit is contained in:
wilsonshih
2023-06-21 10:29:29 +08:00
parent 149fed16df
commit 1761ec1b50

View File

@@ -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;
}
});
}