Defer copy splash screen to client after transaction committed.

For cold launch, usually there is an opening transition. And if the
app has launch another activity, there will do transfer splash screen
to the latest visible activity.
But the transaction of transfer starting window will happen after
first transition, so if core copy the splash screen to client before
the transfer starting window transaction apply, the latest top activity
would still hidden then nothing can be see on the screen.
So like remove starting window, we should also defer the copy action
after transfer starting window transaction done.

Bug: 295458327
Test: launch test app several times, to verify no flickering anymore.
Change-Id: I733fc19bc09cddf8beee01a85283197c0576964a
This commit is contained in:
wilsonshih
2023-08-14 12:14:56 +08:00
parent 9815c0eb7b
commit d8ad772309
2 changed files with 33 additions and 6 deletions

View File

@@ -224,6 +224,9 @@ import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_COPY_TO_CLIENT;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_IDLE;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_REMOVE_DIRECTLY;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
@@ -2684,6 +2687,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (isTransferringSplashScreen()) {
return true;
}
// Only do transfer after transaction has done when starting window exist.
if (mStartingData != null && mStartingData.mWaitForSyncTransactionCommit) {
mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_COPY_TO_CLIENT;
return true;
}
requestCopySplashScreen();
return isTransferringSplashScreen();
}
@@ -2841,11 +2849,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mStartingData == null) {
return;
}
mStartingData.mWaitForSyncTransactionCommit = false;
if (mStartingData.mRemoveAfterTransaction) {
mStartingData.mRemoveAfterTransaction = false;
removeStartingWindowAnimation(mStartingData.mPrepareRemoveAnimation);
final StartingData lastData = mStartingData;
lastData.mWaitForSyncTransactionCommit = false;
if (lastData.mRemoveAfterTransaction == AFTER_TRANSACTION_REMOVE_DIRECTLY) {
removeStartingWindowAnimation(lastData.mPrepareRemoveAnimation);
} else if (lastData.mRemoveAfterTransaction == AFTER_TRANSACTION_COPY_TO_CLIENT) {
removeStartingWindow();
}
lastData.mRemoveAfterTransaction = AFTER_TRANSACTION_IDLE;
}
void removeStartingWindowAnimation(boolean prepareAnimation) {
@@ -2872,7 +2883,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mStartingData != null) {
if (mStartingData.mWaitForSyncTransactionCommit
|| mTransitionController.inCollectingTransition(startingWindow)) {
mStartingData.mRemoveAfterTransaction = true;
mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_REMOVE_DIRECTLY;
mStartingData.mPrepareRemoveAnimation = prepareAnimation;
return;
}

View File

@@ -16,6 +16,8 @@
package com.android.server.wm;
import android.annotation.IntDef;
import com.android.server.wm.StartingSurfaceController.StartingSurface;
/**
@@ -23,6 +25,20 @@ import com.android.server.wm.StartingSurfaceController.StartingSurface;
*/
public abstract class StartingData {
/** Nothing need to do after transaction */
static final int AFTER_TRANSACTION_IDLE = 0;
/** Remove the starting window directly after transaction done. */
static final int AFTER_TRANSACTION_REMOVE_DIRECTLY = 1;
/** Do copy splash screen to client after transaction done. */
static final int AFTER_TRANSACTION_COPY_TO_CLIENT = 2;
@IntDef(prefix = { "AFTER_TRANSACTION" }, value = {
AFTER_TRANSACTION_IDLE,
AFTER_TRANSACTION_REMOVE_DIRECTLY,
AFTER_TRANSACTION_COPY_TO_CLIENT,
})
@interface AfterTransaction {}
protected final WindowManagerService mService;
protected final int mTypeParams;
@@ -60,7 +76,7 @@ public abstract class StartingData {
* This starting window should be removed after applying the start transaction of transition,
* which ensures the app window has shown.
*/
boolean mRemoveAfterTransaction;
@AfterTransaction int mRemoveAfterTransaction;
/** Whether to prepare the removal animation. */
boolean mPrepareRemoveAnimation;