Loading services/core/java/com/android/server/wm/ActivityRecord.java +10 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -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); Loading services/core/java/com/android/server/wm/ActivityStartController.java +5 −0 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -480,6 +484,7 @@ public class ActivityStartController { } } } finally { mService.mWindowManager.mStartingSurfaceController.endDeferAddStartingWindow(); mService.continueWindowLayout(); } } Loading services/core/java/com/android/server/wm/StartingSurfaceController.java +86 −1 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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()); Loading @@ -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; Loading Loading @@ -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; Loading services/core/java/com/android/server/wm/Task.java +2 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +10 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -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); Loading
services/core/java/com/android/server/wm/ActivityStartController.java +5 −0 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -480,6 +484,7 @@ public class ActivityStartController { } } } finally { mService.mWindowManager.mStartingSurfaceController.endDeferAddStartingWindow(); mService.continueWindowLayout(); } } Loading
services/core/java/com/android/server/wm/StartingSurfaceController.java +86 −1 Original line number Diff line number Diff line Loading @@ -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; /** Loading @@ -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()); Loading @@ -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; Loading Loading @@ -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; Loading
services/core/java/com/android/server/wm/Task.java +2 −2 Original line number Diff line number Diff line Loading @@ -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, Loading