Loading services/core/java/com/android/server/am/ActivityRecord.java +25 −4 Original line number Diff line number Diff line Loading @@ -1561,8 +1561,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true; } void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) { mWindowContainerController.notifyAppResumed(wasStopped, allowSavedSurface); void notifyAppResumed(boolean wasStopped) { mWindowContainerController.notifyAppResumed(wasStopped); } void notifyUnknownVisibilityLaunched() { Loading Loading @@ -2112,7 +2112,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo service.compatibilityInfoForPackageLocked(info.applicationInfo); final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags, prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning()); prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(), allowTaskSnapshot()); if (shown) { mStartingWindowState = STARTING_WINDOW_SHOWN; } Loading Loading @@ -2552,7 +2553,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo preserveWindowOnDeferredRelaunch = false; } boolean isProcessRunning() { private boolean isProcessRunning() { ProcessRecord proc = app; if (proc == null) { proc = service.mProcessNames.get(processName, info.applicationInfo.uid); Loading @@ -2560,6 +2561,26 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return proc != null && proc.thread != null; } /** * @return Whether a task snapshot starting window may be shown. */ private boolean allowTaskSnapshot() { if (newIntents == null) { return true; } // Restrict task snapshot starting window to launcher start, or there is no intent at all // (eg. task being brought to front). If the intent is something else, likely the app is // going to show some specific page or view, instead of what's left last time. for (int i = newIntents.size() - 1; i >= 0; i--) { final Intent intent = newIntents.get(i); if (intent != null && !ActivityRecord.isMainIntent(intent)) { return false; } } return true; } void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { out.attribute(null, ATTR_ID, String.valueOf(createTime)); out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid)); Loading services/core/java/com/android/server/am/ActivityStack.java +1 −13 Original line number Diff line number Diff line Loading @@ -2531,26 +2531,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } boolean allowSavedSurface = true; if (next.newIntents != null) { // Restrict saved surface to launcher start, or there is no intent at all // (eg. task being brought to front). If the intent is something else, // likely the app is going to show some specific page or view, instead of // what's left last time. for (int i = next.newIntents.size() - 1; i >= 0; i--) { final Intent intent = next.newIntents.get(i); if (intent != null && !ActivityRecord.isMainIntent(intent)) { allowSavedSurface = false; break; } } next.app.thread.scheduleNewIntent( next.newIntents, next.appToken, false /* andPause */); } // Well the app will no longer be stopped. // Clear app token stopped state in window manager if needed. next.notifyAppResumed(next.stopped, allowSavedSurface); next.notifyAppResumed(next.stopped); EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.getTask().taskId, Loading services/core/java/com/android/server/wm/AppWindowContainerController.java +9 −6 Original line number Diff line number Diff line Loading @@ -449,7 +449,8 @@ public class AppWindowContainerController public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags, IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning) { IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot) { synchronized(mWindowMap) { if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken + " pkg=" + pkg + " transferFrom=" + transferFrom); Loading @@ -469,7 +470,8 @@ public class AppWindowContainerController return false; } final int type = getStartingWindowType(newTask, taskSwitch, processRunning); final int type = getStartingWindowType(newTask, taskSwitch, processRunning, allowTaskSnapshot); if (type == STARTING_WINDOW_TYPE_SNAPSHOT) { return createSnapshot(); Loading Loading @@ -539,10 +541,11 @@ public class AppWindowContainerController return true; } private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning) { private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot) { if (newTask || !processRunning) { return STARTING_WINDOW_TYPE_SPLASH_SCREEN; } else if (taskSwitch) { } else if (taskSwitch && allowTaskSnapshot) { return STARTING_WINDOW_TYPE_SNAPSHOT; } else { return STARTING_WINDOW_TYPE_NONE; Loading Loading @@ -612,13 +615,13 @@ public class AppWindowContainerController } } public void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) { public void notifyAppResumed(boolean wasStopped) { synchronized(mWindowMap) { if (mContainer == null) { Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + mToken); return; } mContainer.notifyAppResumed(wasStopped, allowSavedSurface); mContainer.notifyAppResumed(wasStopped); } } Loading services/core/java/com/android/server/wm/AppWindowToken.java +2 −5 Original line number Diff line number Diff line Loading @@ -582,16 +582,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree * Notify that the app is now resumed, and it was not stopped before, perform a clean * up of the surfaces */ void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) { void notifyAppResumed(boolean wasStopped) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " allowSavedSurface=" + allowSavedSurface + " " + this); + " " + this); mAppStopped = false; if (!wasStopped) { destroySurfaces(true /*cleanupOnResume*/); } if (!allowSavedSurface) { destroySavedSurfaces(); } } /** Loading services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java +5 −5 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { final WindowTestUtils.TestAppWindowContainerController controller = createAppWindowController(); controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false); android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true); waitUntilHandlersIdle(); final AppWindowToken atoken = controller.getAppWindowToken(); assertHasStartingWindow(atoken); Loading @@ -113,11 +113,11 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { final WindowTestUtils.TestAppWindowContainerController controller2 = createAppWindowController(); controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false); android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true); waitUntilHandlersIdle(); controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(), true, true, false); true, true, false, true); waitUntilHandlersIdle(); assertNoStartingWindow(controller1.getAppWindowToken()); assertHasStartingWindow(controller2.getAppWindowToken()); Loading @@ -134,10 +134,10 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { // Surprise, ...! Transfer window in the middle of the creation flow. controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(), true, true, false); true, true, false, true); }); controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false); android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true); waitUntilHandlersIdle(); assertNoStartingWindow(controller1.getAppWindowToken()); assertHasStartingWindow(controller2.getAppWindowToken()); Loading Loading
services/core/java/com/android/server/am/ActivityRecord.java +25 −4 Original line number Diff line number Diff line Loading @@ -1561,8 +1561,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true; } void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) { mWindowContainerController.notifyAppResumed(wasStopped, allowSavedSurface); void notifyAppResumed(boolean wasStopped) { mWindowContainerController.notifyAppResumed(wasStopped); } void notifyUnknownVisibilityLaunched() { Loading Loading @@ -2112,7 +2112,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo service.compatibilityInfoForPackageLocked(info.applicationInfo); final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags, prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning()); prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(), allowTaskSnapshot()); if (shown) { mStartingWindowState = STARTING_WINDOW_SHOWN; } Loading Loading @@ -2552,7 +2553,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo preserveWindowOnDeferredRelaunch = false; } boolean isProcessRunning() { private boolean isProcessRunning() { ProcessRecord proc = app; if (proc == null) { proc = service.mProcessNames.get(processName, info.applicationInfo.uid); Loading @@ -2560,6 +2561,26 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return proc != null && proc.thread != null; } /** * @return Whether a task snapshot starting window may be shown. */ private boolean allowTaskSnapshot() { if (newIntents == null) { return true; } // Restrict task snapshot starting window to launcher start, or there is no intent at all // (eg. task being brought to front). If the intent is something else, likely the app is // going to show some specific page or view, instead of what's left last time. for (int i = newIntents.size() - 1; i >= 0; i--) { final Intent intent = newIntents.get(i); if (intent != null && !ActivityRecord.isMainIntent(intent)) { return false; } } return true; } void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { out.attribute(null, ATTR_ID, String.valueOf(createTime)); out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid)); Loading
services/core/java/com/android/server/am/ActivityStack.java +1 −13 Original line number Diff line number Diff line Loading @@ -2531,26 +2531,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } boolean allowSavedSurface = true; if (next.newIntents != null) { // Restrict saved surface to launcher start, or there is no intent at all // (eg. task being brought to front). If the intent is something else, // likely the app is going to show some specific page or view, instead of // what's left last time. for (int i = next.newIntents.size() - 1; i >= 0; i--) { final Intent intent = next.newIntents.get(i); if (intent != null && !ActivityRecord.isMainIntent(intent)) { allowSavedSurface = false; break; } } next.app.thread.scheduleNewIntent( next.newIntents, next.appToken, false /* andPause */); } // Well the app will no longer be stopped. // Clear app token stopped state in window manager if needed. next.notifyAppResumed(next.stopped, allowSavedSurface); next.notifyAppResumed(next.stopped); EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.getTask().taskId, Loading
services/core/java/com/android/server/wm/AppWindowContainerController.java +9 −6 Original line number Diff line number Diff line Loading @@ -449,7 +449,8 @@ public class AppWindowContainerController public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags, IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning) { IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot) { synchronized(mWindowMap) { if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken + " pkg=" + pkg + " transferFrom=" + transferFrom); Loading @@ -469,7 +470,8 @@ public class AppWindowContainerController return false; } final int type = getStartingWindowType(newTask, taskSwitch, processRunning); final int type = getStartingWindowType(newTask, taskSwitch, processRunning, allowTaskSnapshot); if (type == STARTING_WINDOW_TYPE_SNAPSHOT) { return createSnapshot(); Loading Loading @@ -539,10 +541,11 @@ public class AppWindowContainerController return true; } private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning) { private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot) { if (newTask || !processRunning) { return STARTING_WINDOW_TYPE_SPLASH_SCREEN; } else if (taskSwitch) { } else if (taskSwitch && allowTaskSnapshot) { return STARTING_WINDOW_TYPE_SNAPSHOT; } else { return STARTING_WINDOW_TYPE_NONE; Loading Loading @@ -612,13 +615,13 @@ public class AppWindowContainerController } } public void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) { public void notifyAppResumed(boolean wasStopped) { synchronized(mWindowMap) { if (mContainer == null) { Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + mToken); return; } mContainer.notifyAppResumed(wasStopped, allowSavedSurface); mContainer.notifyAppResumed(wasStopped); } } Loading
services/core/java/com/android/server/wm/AppWindowToken.java +2 −5 Original line number Diff line number Diff line Loading @@ -582,16 +582,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree * Notify that the app is now resumed, and it was not stopped before, perform a clean * up of the surfaces */ void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) { void notifyAppResumed(boolean wasStopped) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " allowSavedSurface=" + allowSavedSurface + " " + this); + " " + this); mAppStopped = false; if (!wasStopped) { destroySurfaces(true /*cleanupOnResume*/); } if (!allowSavedSurface) { destroySavedSurfaces(); } } /** Loading
services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java +5 −5 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { final WindowTestUtils.TestAppWindowContainerController controller = createAppWindowController(); controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false); android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true); waitUntilHandlersIdle(); final AppWindowToken atoken = controller.getAppWindowToken(); assertHasStartingWindow(atoken); Loading @@ -113,11 +113,11 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { final WindowTestUtils.TestAppWindowContainerController controller2 = createAppWindowController(); controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false); android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true); waitUntilHandlersIdle(); controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(), true, true, false); true, true, false, true); waitUntilHandlersIdle(); assertNoStartingWindow(controller1.getAppWindowToken()); assertHasStartingWindow(controller2.getAppWindowToken()); Loading @@ -134,10 +134,10 @@ public class AppWindowContainerControllerTests extends WindowTestsBase { // Surprise, ...! Transfer window in the middle of the creation flow. controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(), true, true, false); true, true, false, true); }); controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(), android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false); android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true); waitUntilHandlersIdle(); assertNoStartingWindow(controller1.getAppWindowToken()); assertHasStartingWindow(controller2.getAppWindowToken()); Loading