Loading core/java/android/app/ActivityManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -592,6 +592,14 @@ public class ActivityManager { public static boolean isAlwaysOnTop(int stackId) { return stackId == PINNED_STACK_ID; } /** * Returns true if the top task in the task is allowed to return home when finished and * there are other tasks in the stack. */ public static boolean allowTopTaskToReturnHome(int stackId) { return stackId != PINNED_STACK_ID; } } /** Loading services/core/java/com/android/server/am/ActivityRecord.java +8 −6 Original line number Diff line number Diff line Loading @@ -171,7 +171,9 @@ final class ActivityRecord { boolean stopped; // is activity pause finished? boolean delayedResume; // not yet resumed because of stopped app switches? boolean finishing; // activity in pending finish list? boolean configDestroy; // need to destroy due to config change? boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is // completed boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch int configChangeFlags; // which config values have changed boolean keysPaused; // has key dispatching been paused for it? int launchMode; // the launch mode activity attribute. Loading @@ -184,9 +186,9 @@ final class ActivityRecord { boolean immersive; // immersive mode (don't interrupt if possible) boolean forceNewConfig; // force re-create with new config next time int launchCount; // count of launches since last state long lastLaunchTime; // time of last lauch of this activity long lastLaunchTime; // time of last launch of this activity boolean isVrActivity; // is the activity running in VR mode? ArrayList<ActivityContainer> mChildContainers = new ArrayList<ActivityContainer>(); ArrayList<ActivityContainer> mChildContainers = new ArrayList<>(); String stringName; // for caching of toString(). Loading Loading @@ -341,8 +343,8 @@ final class ActivityRecord { else TimeUtils.formatDuration(lastVisibleTime, now, pw); pw.println(); } if (configDestroy || configChangeFlags != 0) { pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy); if (deferRelaunchUntilPaused || configChangeFlags != 0) { pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused); pw.print(" configChangeFlags="); pw.println(Integer.toHexString(configChangeFlags)); } Loading Loading @@ -551,7 +553,7 @@ final class ActivityRecord { stopped = false; delayedResume = false; finishing = false; configDestroy = false; deferRelaunchUntilPaused = false; keysPaused = false; inHistory = false; visible = false; Loading services/core/java/com/android/server/am/ActivityStack.java +27 −31 Original line number Diff line number Diff line Loading @@ -1088,7 +1088,7 @@ final class ActivityStack { if (r.finishing) { r.clearOptionsLocked(); } else { if (r.configDestroy) { if (r.deferRelaunchUntilPaused) { destroyActivityLocked(r, true, "stop-config"); mStackSupervisor.resumeFocusedStackTopActivityLocked(); } else { Loading @@ -1114,14 +1114,11 @@ final class ActivityStack { if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause, no longer waiting: " + prev); } if (prev.configDestroy) { // The previous is being paused because the configuration // is changing, which means it is actually stopping... // To juggle the fact that we are also starting a new // instance right now, we need to first completely stop // the current instance before starting the new one. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev); destroyActivityLocked(prev, true, "pause-config"); if (prev.deferRelaunchUntilPaused) { // Complete the deferred relaunch that was waiting for pause to complete. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); relaunchActivityLocked(prev, prev.configChangeFlags, false, prev.preserveWindowOnDeferredRelaunch); } else if (wasStopping) { // We are also stopping, the stop request must have gone soon after the pause. // We can't clobber it, because the stop confirmation will not be handled. Loading Loading @@ -2318,11 +2315,12 @@ final class ActivityStack { ActivityStack lastStack = mStackSupervisor.getLastStack(); final boolean fromHome = lastStack.isHomeStack(); if (!isHomeStack() && (fromHome || topTask() != task)) { task.setTaskToReturnTo(fromHome ? lastStack.topTask() == null ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType : APPLICATION_ACTIVITY_TYPE); int returnToType = APPLICATION_ACTIVITY_TYPE; if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) { returnToType = lastStack.topTask() == null ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType; } task.setTaskToReturnTo(returnToType); } } else { task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); Loading Loading @@ -2972,7 +2970,7 @@ final class ActivityStack { r.stopped = true; if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r); r.state = ActivityState.STOPPED; if (r.configDestroy) { if (r.deferRelaunchUntilPaused) { destroyActivityLocked(r, true, "stop-except"); } } Loading Loading @@ -3403,7 +3401,7 @@ final class ActivityStack { } mService.resetFocusedActivityIfNeededLocked(r); r.configDestroy = false; r.deferRelaunchUntilPaused = false; r.frozenBeforeDestroy = false; if (setState) { Loading Loading @@ -4175,38 +4173,33 @@ final class ActivityStack { r.configChangeFlags |= changes; r.startFreezingScreenLocked(r.app, globalChanges); r.forceNewConfig = false; preserveWindow &= isResizeOnlyChange(changes); if (r.app == null || r.app.thread == null) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is destroying non-running " + r); destroyActivityLocked(r, true, "config"); } else if (r.state == ActivityState.PAUSING) { // A little annoying: we are waiting for this activity to // finish pausing. Let's not do anything now, but just // flag that it needs to be restarted when done pausing. // A little annoying: we are waiting for this activity to finish pausing. Let's not // do anything now, but just flag that it needs to be restarted when done pausing. if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is skipping already pausing " + r); r.configDestroy = true; r.deferRelaunchUntilPaused = true; r.preserveWindowOnDeferredRelaunch = preserveWindow; return true; } else if (r.state == ActivityState.RESUMED) { // Try to optimize this case: the configuration is changing // and we need to restart the top, resumed activity. // Instead of doing the normal handshaking, just say // Try to optimize this case: the configuration is changing and we need to restart // the top, resumed activity. Instead of doing the normal handshaking, just say // "restart!". if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is relaunching resumed " + r); relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow && isResizeOnlyChange(changes)); r.configChangeFlags = 0; relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow); } else { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is relaunching non-resumed " + r); relaunchActivityLocked(r, r.configChangeFlags, false, preserveWindow && isResizeOnlyChange(changes)); r.configChangeFlags = 0; relaunchActivityLocked(r, r.configChangeFlags, false, preserveWindow); } // All done... tell the caller we weren't able to keep this // activity around. // All done... tell the caller we weren't able to keep this activity around. return false; } Loading Loading @@ -4298,6 +4291,7 @@ final class ActivityStack { private void relaunchActivityLocked( ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) { if (mService.mSuppressResizeConfigChanges && preserveWindow) { r.configChangeFlags = 0; return; } Loading Loading @@ -4341,6 +4335,8 @@ final class ActivityStack { mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); r.state = ActivityState.PAUSED; } r.configChangeFlags = 0; } boolean willActivityBeVisibleLocked(IBinder token) { Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +3 −3 Original line number Diff line number Diff line Loading @@ -2722,7 +2722,7 @@ public final class ActivityStackSupervisor implements DisplayListener { for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { ActivityRecord s = mStoppingActivities.get(activityNdx); final boolean waitingVisible = mWaitingVisibleActivities.contains(s); if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); if (waitingVisible && nowVisible) { mWaitingVisibleActivities.remove(s); Loading @@ -2732,12 +2732,12 @@ public final class ActivityStackSupervisor implements DisplayListener { // so get rid of it. Otherwise, we need to go through the // normal flow and hide it once we determine that it is // hidden by the activities in front of it. if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s); if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); mWindowManager.setAppVisibility(s.appToken, false); } } if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s); if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); if (stops == null) { stops = new ArrayList<>(); } Loading Loading
core/java/android/app/ActivityManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -592,6 +592,14 @@ public class ActivityManager { public static boolean isAlwaysOnTop(int stackId) { return stackId == PINNED_STACK_ID; } /** * Returns true if the top task in the task is allowed to return home when finished and * there are other tasks in the stack. */ public static boolean allowTopTaskToReturnHome(int stackId) { return stackId != PINNED_STACK_ID; } } /** Loading
services/core/java/com/android/server/am/ActivityRecord.java +8 −6 Original line number Diff line number Diff line Loading @@ -171,7 +171,9 @@ final class ActivityRecord { boolean stopped; // is activity pause finished? boolean delayedResume; // not yet resumed because of stopped app switches? boolean finishing; // activity in pending finish list? boolean configDestroy; // need to destroy due to config change? boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is // completed boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch int configChangeFlags; // which config values have changed boolean keysPaused; // has key dispatching been paused for it? int launchMode; // the launch mode activity attribute. Loading @@ -184,9 +186,9 @@ final class ActivityRecord { boolean immersive; // immersive mode (don't interrupt if possible) boolean forceNewConfig; // force re-create with new config next time int launchCount; // count of launches since last state long lastLaunchTime; // time of last lauch of this activity long lastLaunchTime; // time of last launch of this activity boolean isVrActivity; // is the activity running in VR mode? ArrayList<ActivityContainer> mChildContainers = new ArrayList<ActivityContainer>(); ArrayList<ActivityContainer> mChildContainers = new ArrayList<>(); String stringName; // for caching of toString(). Loading Loading @@ -341,8 +343,8 @@ final class ActivityRecord { else TimeUtils.formatDuration(lastVisibleTime, now, pw); pw.println(); } if (configDestroy || configChangeFlags != 0) { pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy); if (deferRelaunchUntilPaused || configChangeFlags != 0) { pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused); pw.print(" configChangeFlags="); pw.println(Integer.toHexString(configChangeFlags)); } Loading Loading @@ -551,7 +553,7 @@ final class ActivityRecord { stopped = false; delayedResume = false; finishing = false; configDestroy = false; deferRelaunchUntilPaused = false; keysPaused = false; inHistory = false; visible = false; Loading
services/core/java/com/android/server/am/ActivityStack.java +27 −31 Original line number Diff line number Diff line Loading @@ -1088,7 +1088,7 @@ final class ActivityStack { if (r.finishing) { r.clearOptionsLocked(); } else { if (r.configDestroy) { if (r.deferRelaunchUntilPaused) { destroyActivityLocked(r, true, "stop-config"); mStackSupervisor.resumeFocusedStackTopActivityLocked(); } else { Loading @@ -1114,14 +1114,11 @@ final class ActivityStack { if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause, no longer waiting: " + prev); } if (prev.configDestroy) { // The previous is being paused because the configuration // is changing, which means it is actually stopping... // To juggle the fact that we are also starting a new // instance right now, we need to first completely stop // the current instance before starting the new one. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev); destroyActivityLocked(prev, true, "pause-config"); if (prev.deferRelaunchUntilPaused) { // Complete the deferred relaunch that was waiting for pause to complete. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); relaunchActivityLocked(prev, prev.configChangeFlags, false, prev.preserveWindowOnDeferredRelaunch); } else if (wasStopping) { // We are also stopping, the stop request must have gone soon after the pause. // We can't clobber it, because the stop confirmation will not be handled. Loading Loading @@ -2318,11 +2315,12 @@ final class ActivityStack { ActivityStack lastStack = mStackSupervisor.getLastStack(); final boolean fromHome = lastStack.isHomeStack(); if (!isHomeStack() && (fromHome || topTask() != task)) { task.setTaskToReturnTo(fromHome ? lastStack.topTask() == null ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType : APPLICATION_ACTIVITY_TYPE); int returnToType = APPLICATION_ACTIVITY_TYPE; if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) { returnToType = lastStack.topTask() == null ? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType; } task.setTaskToReturnTo(returnToType); } } else { task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE); Loading Loading @@ -2972,7 +2970,7 @@ final class ActivityStack { r.stopped = true; if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r); r.state = ActivityState.STOPPED; if (r.configDestroy) { if (r.deferRelaunchUntilPaused) { destroyActivityLocked(r, true, "stop-except"); } } Loading Loading @@ -3403,7 +3401,7 @@ final class ActivityStack { } mService.resetFocusedActivityIfNeededLocked(r); r.configDestroy = false; r.deferRelaunchUntilPaused = false; r.frozenBeforeDestroy = false; if (setState) { Loading Loading @@ -4175,38 +4173,33 @@ final class ActivityStack { r.configChangeFlags |= changes; r.startFreezingScreenLocked(r.app, globalChanges); r.forceNewConfig = false; preserveWindow &= isResizeOnlyChange(changes); if (r.app == null || r.app.thread == null) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is destroying non-running " + r); destroyActivityLocked(r, true, "config"); } else if (r.state == ActivityState.PAUSING) { // A little annoying: we are waiting for this activity to // finish pausing. Let's not do anything now, but just // flag that it needs to be restarted when done pausing. // A little annoying: we are waiting for this activity to finish pausing. Let's not // do anything now, but just flag that it needs to be restarted when done pausing. if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is skipping already pausing " + r); r.configDestroy = true; r.deferRelaunchUntilPaused = true; r.preserveWindowOnDeferredRelaunch = preserveWindow; return true; } else if (r.state == ActivityState.RESUMED) { // Try to optimize this case: the configuration is changing // and we need to restart the top, resumed activity. // Instead of doing the normal handshaking, just say // Try to optimize this case: the configuration is changing and we need to restart // the top, resumed activity. Instead of doing the normal handshaking, just say // "restart!". if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is relaunching resumed " + r); relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow && isResizeOnlyChange(changes)); r.configChangeFlags = 0; relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow); } else { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is relaunching non-resumed " + r); relaunchActivityLocked(r, r.configChangeFlags, false, preserveWindow && isResizeOnlyChange(changes)); r.configChangeFlags = 0; relaunchActivityLocked(r, r.configChangeFlags, false, preserveWindow); } // All done... tell the caller we weren't able to keep this // activity around. // All done... tell the caller we weren't able to keep this activity around. return false; } Loading Loading @@ -4298,6 +4291,7 @@ final class ActivityStack { private void relaunchActivityLocked( ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) { if (mService.mSuppressResizeConfigChanges && preserveWindow) { r.configChangeFlags = 0; return; } Loading Loading @@ -4341,6 +4335,8 @@ final class ActivityStack { mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); r.state = ActivityState.PAUSED; } r.configChangeFlags = 0; } boolean willActivityBeVisibleLocked(IBinder token) { Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +3 −3 Original line number Diff line number Diff line Loading @@ -2722,7 +2722,7 @@ public final class ActivityStackSupervisor implements DisplayListener { for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { ActivityRecord s = mStoppingActivities.get(activityNdx); final boolean waitingVisible = mWaitingVisibleActivities.contains(s); if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); if (waitingVisible && nowVisible) { mWaitingVisibleActivities.remove(s); Loading @@ -2732,12 +2732,12 @@ public final class ActivityStackSupervisor implements DisplayListener { // so get rid of it. Otherwise, we need to go through the // normal flow and hide it once we determine that it is // hidden by the activities in front of it. if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s); if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); mWindowManager.setAppVisibility(s.appToken, false); } } if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) { if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s); if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s); if (stops == null) { stops = new ArrayList<>(); } Loading