Merge "Prevent the splashscreenview be replaced after transfer starting window" into sc-dev

This commit is contained in:
Wei Sheng Shih
2021-05-25 11:24:56 +00:00
committed by Android (Google) Code Review
2 changed files with 26 additions and 18 deletions

View File

@@ -277,8 +277,9 @@ public class StartingSurfaceDrawer {
// waiting for setContentView before relayoutWindow // waiting for setContentView before relayoutWindow
SplashScreenView contentView = viewSupplier.get(); SplashScreenView contentView = viewSupplier.get();
final StartingWindowRecord record = mStartingWindowRecords.get(taskId); final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
// if record == null, either the starting window added fail or removed already. // If record == null, either the starting window added fail or removed already.
if (record != null) { // Do not add this view if the token is mismatch.
if (record != null && appToken == record.mAppToken) {
// if view == null then creation of content view was failed. // if view == null then creation of content view was failed.
if (contentView != null) { if (contentView != null) {
try { try {
@@ -297,15 +298,16 @@ public class StartingSurfaceDrawer {
try { try {
final WindowManager wm = context.getSystemService(WindowManager.class); final WindowManager wm = context.getSystemService(WindowManager.class);
postAddWindow(taskId, appToken, rootLayout, wm, params); if (postAddWindow(taskId, appToken, rootLayout, wm, params)) {
// We use the splash screen worker thread to create SplashScreenView while adding
// We use the splash screen worker thread to create SplashScreenView while adding the // the window, as otherwise Choreographer#doFrame might be delayed on this thread.
// window, as otherwise Choreographer#doFrame might be delayed on this thread. // And since Choreographer#doFrame won't happen immediately after adding the window,
// And since Choreographer#doFrame won't happen immediately after adding the window, if // if the view is not added to the PhoneWindow on the first #doFrame, the view will
// the view is not added to the PhoneWindow on the first #doFrame, the view will not be // not be rendered on the first frame. So here we need to synchronize the view on
// rendered on the first frame. So here we need to synchronize the view on the window // the window before first round relayoutWindow, which will happen after insets
// before first round relayoutWindow, which will happen after insets animation. // animation.
mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null); mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
}
} catch (RuntimeException e) { } catch (RuntimeException e) {
// don't crash if something else bad happens, for example a // don't crash if something else bad happens, for example a
// failure loading resources because we are loading from an app // failure loading resources because we are loading from an app
@@ -347,7 +349,8 @@ public class StartingSurfaceDrawer {
final int taskId = startingWindowInfo.taskInfo.taskId; final int taskId = startingWindowInfo.taskInfo.taskId;
final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken,
snapshot, mSplashScreenExecutor, () -> removeWindowNoAnimate(taskId)); snapshot, mSplashScreenExecutor, () -> removeWindowNoAnimate(taskId));
final StartingWindowRecord tView = new StartingWindowRecord(null/* decorView */, surface); final StartingWindowRecord tView = new StartingWindowRecord(appToken,
null/* decorView */, surface);
mStartingWindowRecords.put(taskId, tView); mStartingWindowRecords.put(taskId, tView);
} }
@@ -382,7 +385,7 @@ public class StartingSurfaceDrawer {
ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable); ActivityTaskManager.getInstance().onSplashScreenViewCopyFinished(taskId, parcelable);
} }
protected void postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm, protected boolean postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm,
WindowManager.LayoutParams params) { WindowManager.LayoutParams params) {
boolean shouldSaveView = true; boolean shouldSaveView = true;
try { try {
@@ -401,12 +404,13 @@ public class StartingSurfaceDrawer {
} }
if (shouldSaveView) { if (shouldSaveView) {
removeWindowNoAnimate(taskId); removeWindowNoAnimate(taskId);
saveSplashScreenRecord(taskId, view); saveSplashScreenRecord(appToken, taskId, view);
} }
return shouldSaveView;
} }
private void saveSplashScreenRecord(int taskId, View view) { private void saveSplashScreenRecord(IBinder appToken, int taskId, View view) {
final StartingWindowRecord tView = new StartingWindowRecord(view, final StartingWindowRecord tView = new StartingWindowRecord(appToken, view,
null/* TaskSnapshotWindow */); null/* TaskSnapshotWindow */);
mStartingWindowRecords.put(taskId, tView); mStartingWindowRecords.put(taskId, tView);
} }
@@ -468,12 +472,15 @@ public class StartingSurfaceDrawer {
* Record the view or surface for a starting window. * Record the view or surface for a starting window.
*/ */
private static class StartingWindowRecord { private static class StartingWindowRecord {
private final IBinder mAppToken;
private final View mDecorView; private final View mDecorView;
private final TaskSnapshotWindow mTaskSnapshotWindow; private final TaskSnapshotWindow mTaskSnapshotWindow;
private SplashScreenView mContentView; private SplashScreenView mContentView;
private boolean mSetSplashScreen; private boolean mSetSplashScreen;
StartingWindowRecord(View decorView, TaskSnapshotWindow taskSnapshotWindow) { StartingWindowRecord(IBinder appToken, View decorView,
TaskSnapshotWindow taskSnapshotWindow) {
mAppToken = appToken;
mDecorView = decorView; mDecorView = decorView;
mTaskSnapshotWindow = taskSnapshotWindow; mTaskSnapshotWindow = taskSnapshotWindow;
} }

View File

@@ -83,11 +83,12 @@ public class StartingSurfaceDrawerTests {
} }
@Override @Override
protected void postAddWindow(int taskId, IBinder appToken, protected boolean postAddWindow(int taskId, IBinder appToken,
View view, WindowManager wm, WindowManager.LayoutParams params) { View view, WindowManager wm, WindowManager.LayoutParams params) {
// listen for addView // listen for addView
mAddWindowForTask = taskId; mAddWindowForTask = taskId;
mViewThemeResId = view.getContext().getThemeResId(); mViewThemeResId = view.getContext().getThemeResId();
return true;
} }
@Override @Override