Merge "Deferring add splash screen window when launch with startActivities"
This commit is contained in:
committed by
Android (Google) Code Review
commit
3dac854527
@@ -2134,7 +2134,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
return activityInfo != null ? activityInfo.applicationInfo : null;
|
||||
});
|
||||
|
||||
final int typeParameter = mWmService.mStartingSurfaceController
|
||||
final int typeParameter = StartingSurfaceController
|
||||
.makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning,
|
||||
allowTaskSnapshot, activityCreated, useEmpty, useLegacy, activityAllDrawn);
|
||||
|
||||
@@ -6616,13 +6616,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
return splashScreenThemeResId;
|
||||
}
|
||||
|
||||
void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
|
||||
boolean startActivity, ActivityRecord sourceRecord) {
|
||||
showStartingWindow(prev, newTask, taskSwitch, isProcessRunning(), startActivity,
|
||||
sourceRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param prev Previous activity which contains a starting window.
|
||||
* @param processRunning Whether the client process is running.
|
||||
* @param startActivity Whether this activity is just created from starter.
|
||||
* @param sourceRecord The source activity which start this activity.
|
||||
*/
|
||||
void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
|
||||
boolean startActivity, ActivityRecord sourceRecord) {
|
||||
boolean processRunning, boolean startActivity, ActivityRecord sourceRecord) {
|
||||
if (mTaskOverlay) {
|
||||
// We don't show starting window for overlay activities.
|
||||
return;
|
||||
@@ -6647,7 +6654,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
&& task.getActivity((r) -> !r.finishing && r != this) == null;
|
||||
|
||||
final boolean scheduled = addStartingWindow(packageName, resolvedTheme,
|
||||
prev, newTask || newSingleActivity, taskSwitch, isProcessRunning(),
|
||||
prev, newTask || newSingleActivity, taskSwitch, processRunning,
|
||||
allowTaskSnapshot(), activityCreated, mSplashScreenStyleEmpty, allDrawn);
|
||||
if (DEBUG_STARTING_WINDOW_VERBOSE && scheduled) {
|
||||
Slog.d(TAG, "Scheduled starting window for " + this);
|
||||
|
||||
@@ -455,6 +455,10 @@ public class ActivityStartController {
|
||||
// Lock the loop to ensure the activities launched in a sequence.
|
||||
synchronized (mService.mGlobalLock) {
|
||||
mService.deferWindowLayout();
|
||||
// To avoid creating multiple starting window when creating starting multiples
|
||||
// activities, we defer the creation of the starting window once all start request
|
||||
// are processed
|
||||
mService.mWindowManager.mStartingSurfaceController.beginDeferAddStartingWindow();
|
||||
try {
|
||||
for (int i = 0; i < starters.length; i++) {
|
||||
final int startResult = starters[i].setResultTo(resultTo)
|
||||
@@ -480,6 +484,7 @@ public class ActivityStartController {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mService.mWindowManager.mStartingSurfaceController.endDeferAddStartingWindow();
|
||||
mService.continueWindowLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.util.Slog;
|
||||
import android.window.TaskSnapshot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
@@ -45,6 +46,14 @@ public class StartingSurfaceController {
|
||||
private final WindowManagerService mService;
|
||||
private final SplashScreenExceptionList mSplashScreenExceptionsList;
|
||||
|
||||
// Cache status while deferring add starting window
|
||||
boolean mInitProcessRunning;
|
||||
boolean mInitNewTask;
|
||||
boolean mInitTaskSwitch;
|
||||
private final ArrayList<DeferringStartingWindowRecord> mDeferringAddStartActivities =
|
||||
new ArrayList<>();
|
||||
private boolean mDeferringAddStartingWindow;
|
||||
|
||||
public StartingSurfaceController(WindowManagerService wm) {
|
||||
mService = wm;
|
||||
mSplashScreenExceptionsList = new SplashScreenExceptionList(wm.mContext.getMainExecutor());
|
||||
@@ -70,7 +79,7 @@ public class StartingSurfaceController {
|
||||
return mSplashScreenExceptionsList.isException(packageName, targetSdk, infoProvider);
|
||||
}
|
||||
|
||||
int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
|
||||
static int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
|
||||
boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated,
|
||||
boolean useEmpty, boolean useLegacy, boolean activityDrawn) {
|
||||
int parameter = 0;
|
||||
@@ -142,6 +151,82 @@ public class StartingSurfaceController {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DeferringStartingWindowRecord {
|
||||
final ActivityRecord mDeferring;
|
||||
final ActivityRecord mPrev;
|
||||
final ActivityRecord mSource;
|
||||
|
||||
DeferringStartingWindowRecord(ActivityRecord deferring, ActivityRecord prev,
|
||||
ActivityRecord source) {
|
||||
mDeferring = deferring;
|
||||
mPrev = prev;
|
||||
mSource = source;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a starting window while starting a new activity. Do not use this method to create a
|
||||
* starting window for an existing activity.
|
||||
*/
|
||||
void showStartingWindow(ActivityRecord target, ActivityRecord prev,
|
||||
boolean newTask, boolean isTaskSwitch, ActivityRecord source) {
|
||||
if (mDeferringAddStartingWindow) {
|
||||
addDeferringRecord(target, prev, newTask, isTaskSwitch, source);
|
||||
} else {
|
||||
target.showStartingWindow(prev, newTask, isTaskSwitch, true /* startActivity */,
|
||||
source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queueing the starting activity status while deferring add starting window.
|
||||
* @see Task#startActivityLocked
|
||||
*/
|
||||
private void addDeferringRecord(ActivityRecord deferring, ActivityRecord prev,
|
||||
boolean newTask, boolean isTaskSwitch, ActivityRecord source) {
|
||||
// Set newTask, taskSwitch, processRunning form first activity because those can change
|
||||
// after first activity started.
|
||||
if (mDeferringAddStartActivities.isEmpty()) {
|
||||
mInitProcessRunning = deferring.isProcessRunning();
|
||||
mInitNewTask = newTask;
|
||||
mInitTaskSwitch = isTaskSwitch;
|
||||
}
|
||||
mDeferringAddStartActivities.add(new DeferringStartingWindowRecord(
|
||||
deferring, prev, source));
|
||||
}
|
||||
|
||||
private void showStartingWindowFromDeferringActivities() {
|
||||
// Attempt to add starting window from the top-most activity.
|
||||
for (int i = mDeferringAddStartActivities.size() - 1; i >= 0; --i) {
|
||||
final DeferringStartingWindowRecord next = mDeferringAddStartActivities.get(i);
|
||||
next.mDeferring.showStartingWindow(next.mPrev, mInitNewTask, mInitTaskSwitch,
|
||||
mInitProcessRunning, true /* startActivity */, next.mSource);
|
||||
// If one succeeds, it is done.
|
||||
if (next.mDeferring.mStartingData != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mDeferringAddStartActivities.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin deferring add starting window in one pass.
|
||||
* This is used to deferring add starting window while starting multiples activities because
|
||||
* system only need to provide a starting window to the top-visible activity.
|
||||
* Most call {@link #endDeferAddStartingWindow} when starting activities process finished.
|
||||
* @see #endDeferAddStartingWindow()
|
||||
*/
|
||||
void beginDeferAddStartingWindow() {
|
||||
mDeferringAddStartingWindow = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* End deferring add starting window.
|
||||
*/
|
||||
void endDeferAddStartingWindow() {
|
||||
mDeferringAddStartingWindow = false;
|
||||
showStartingWindowFromDeferringActivities();
|
||||
}
|
||||
|
||||
final class StartingSurface {
|
||||
private final Task mTask;
|
||||
|
||||
@@ -5149,8 +5149,8 @@ class Task extends TaskFragment {
|
||||
|
||||
final ActivityRecord prev = baseTask.getActivity(
|
||||
a -> a.mStartingData != null && a.showToCurrentUser());
|
||||
r.showStartingWindow(prev, newTask, isTaskSwitch,
|
||||
true /* startActivity */, sourceRecord);
|
||||
mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask,
|
||||
isTaskSwitch, sourceRecord);
|
||||
}
|
||||
} else {
|
||||
// If this is the first activity, don't do any fancy animations,
|
||||
|
||||
Reference in New Issue
Block a user