Loading api/test-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -4031,6 +4031,8 @@ package android.app { method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect); method public android.app.ActivityOptions setLaunchDisplayId(int); method public void setLaunchStackId(int); method public void setLaunchTaskId(int); method public void setTaskOverlay(boolean, boolean); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time"; core/java/android/app/ActivityOptions.java +2 −0 Original line number Diff line number Diff line Loading @@ -1068,6 +1068,7 @@ public class ActivityOptions { * Sets the task the activity will be launched in. * @hide */ @TestApi public void setLaunchTaskId(int taskId) { mLaunchTaskId = taskId; } Loading @@ -1085,6 +1086,7 @@ public class ActivityOptions { * the task will also not be moved to the front of the stack. * @hide */ @TestApi public void setTaskOverlay(boolean taskOverlay, boolean canResume) { mTaskOverlay = taskOverlay; mTaskOverlayCanResume = canResume; Loading packages/Shell/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ <uses-permission android:name="android.permission.GET_APP_OPS_STATS" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> <uses-permission android:name="android.permission.MANAGE_AUTO_FILL" /> Loading services/core/java/com/android/server/am/ActivityManagerShellCommand.java +18 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,8 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.view.Display.INVALID_DISPLAY; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; final class ActivityManagerShellCommand extends ShellCommand { public static final String NO_CLASS_ERROR_CODE = "Error type 3"; private static final String SHELL_PACKAGE_NAME = "com.android.shell"; Loading Loading @@ -118,6 +120,8 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mStreaming; // Streaming the profiling output to a file. private int mDisplayId; private int mStackId; private int mTaskId; private boolean mIsTaskOverlay; final boolean mDumping; Loading Loading @@ -263,6 +267,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mUserId = defUser; mDisplayId = INVALID_DISPLAY; mStackId = INVALID_STACK_ID; mTaskId = INVALID_TASK_ID; mIsTaskOverlay = false; return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { @Override Loading Loading @@ -297,6 +303,10 @@ final class ActivityManagerShellCommand extends ShellCommand { mDisplayId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--stack")) { mStackId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--task")) { mTaskId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--task-overlay")) { mIsTaskOverlay = true; } else { return false; } Loading Loading @@ -380,6 +390,14 @@ final class ActivityManagerShellCommand extends ShellCommand { options = ActivityOptions.makeBasic(); options.setLaunchStackId(mStackId); } if (mTaskId != INVALID_TASK_ID) { options = ActivityOptions.makeBasic(); options.setLaunchTaskId(mTaskId); if (mIsTaskOverlay) { options.setTaskOverlay(true, true /* canResume */); } } if (mWaitOption) { result = mInterface.startActivityAndWait(null, null, intent, mimeType, null, null, 0, mStartFlags, profilerInfo, Loading services/core/java/com/android/server/am/ActivityStack.java +70 −27 Original line number Diff line number Diff line Loading @@ -67,7 +67,9 @@ import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; import static com.android.server.am.ActivityStackSupervisor.ON_TOP; import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE; import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; import static com.android.server.wm.AppTransition.TRANSIT_NONE; Loading Loading @@ -121,7 +123,6 @@ import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.StackWindowController; import com.android.server.wm.StackWindowListener; import com.android.server.wm.TaskStack; import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; Loading Loading @@ -1185,13 +1186,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * @param resuming The activity we are currently trying to resume or null if this is not being * called as part of resuming the top activity, so we shouldn't try to instigate * a resume here if not null. * @param dontWait True if the caller does not want to wait for the pause to complete. If * set to true, we will immediately complete the pause here before returning. * @param pauseImmediately True if the caller does not want to wait for the activity callback to * complete pausing. * @return Returns true if an activity now is in the PAUSING state, and we are waiting for * it to tell us when it is done. */ final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean dontWait) { ActivityRecord resuming, boolean pauseImmediately) { if (mPausingActivity != null) { Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + " state=" + mPausingActivity.state); Loading @@ -1213,7 +1214,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (mActivityContainer.mParentActivity == null) { // Top level stack, not a child. Look for child stacks. mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait); mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, pauseImmediately); } if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); Loading Loading @@ -1243,7 +1245,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai prev.shortComponentName); mService.updateUsageStats(prev, false); prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); userLeaving, prev.configChangeFlags, pauseImmediately); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. Slog.w(TAG, "Exception thrown during pause", e); Loading Loading @@ -1274,7 +1276,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); } if (dontWait) { if (pauseImmediately) { // If the caller said they don't want to wait for the pause, then complete // the pause now. completePauseLocked(false, resuming); Loading Loading @@ -3487,12 +3489,20 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.icicle = null; } /** * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)} */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY); } /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { String reason, boolean oomAdj, boolean pauseImmediately) { if (r.finishing) { Slog.w(TAG, "Duplicate finish request for " + r); return false; Loading Loading @@ -3530,7 +3540,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + r); if (endTask) { mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(task.taskId); mService.mTaskChangeNotificationController.notifyTaskRemovalStarted( task.taskId); } mWindowManager.prepareAppTransition(transit, false); Loading @@ -3541,7 +3552,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r); if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false"); startPausingLocked(false, false, null, false); startPausingLocked(false, false, null, pauseImmediately); } if (endTask) { Loading @@ -3552,15 +3563,30 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // it is done pausing; else we can just directly finish it here. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r); if (r.visible) { mWindowManager.prepareAppTransition(transit, false); r.setVisibility(false); mWindowManager.executeAppTransition(); if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { mStackSupervisor.mWaitingVisibleActivities.add(r); prepareActivityHideTransitionAnimation(r, transit); } final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE; final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj) == null; // The following code is an optimization. When the last non-task overlay activity // is removed from the task, we remove the entire task from the stack. However, // since that is done after the scheduled destroy callback from the activity, that // call to change the visibility of the task overlay activities would be out of // sync with the activitiy visibility being set for this finishing activity above. // In this case, we can set the visibility of all the task overlay activities when // we detect the last one is finishing to keep them in sync. if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) { for (ActivityRecord taskOverlay : task.mActivities) { if (!taskOverlay.mTaskOverlay) { continue; } prepareActivityHideTransitionAnimation(taskOverlay, transit); } } return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null; return removedActivity; } else { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r); } Loading @@ -3571,6 +3597,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) { mWindowManager.prepareAppTransition(transit, false); r.setVisibility(false); mWindowManager.executeAppTransition(); if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { mStackSupervisor.mWaitingVisibleActivities.add(r); } } static final int FINISH_IMMEDIATELY = 0; static final int FINISH_AFTER_PAUSE = 1; static final int FINISH_AFTER_VISIBLE = 2; Loading Loading @@ -3864,15 +3899,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.removeWindowContainer(); final TaskRecord task = r.task; final boolean lastActivity = task != null ? task.removeActivity(r) : false; // If we are removing the last activity in the task, not including task overlay activities, // then fall through into the block below to remove the entire task itself final boolean onlyHasTaskOverlays = task != null ? task.onlyHasTaskOverlayActivities(false /* excludingFinishing */) : false; if (lastActivity || onlyHasTaskOverlays) { if (DEBUG_STACK) { Slog.i(TAG_STACK, "removeActivityFromHistoryLocked: last activity removed from " + this + " onlyHasTaskOverlays=" + onlyHasTaskOverlays); } if (lastActivity) { if (DEBUG_STACK) Slog.i(TAG_STACK, "removeActivityFromHistoryLocked: last activity removed from " + this); if (mStackSupervisor.isFocusedStack(this) && task == topTask() && task.isOverHomeStack()) { mStackSupervisor.moveHomeStackTaskToTop(reason); } removeTask(task, reason); removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } cleanUpActivityServicesLocked(r); r.removeUriPermissionsLocked(); Loading Loading @@ -4923,10 +4966,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return starting; } void removeTask(TaskRecord task, String reason) { removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } /** * Removes the input task from this stack. * @param task to remove. Loading @@ -4936,6 +4975,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai */ void removeTask(TaskRecord task, String reason, int mode) { if (mode == REMOVE_TASK_MODE_DESTROYING) { // When destroying a task, tell the supervisor to remove it so that any activity it has // can be cleaned up correctly mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */, !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY); task.removeWindowContainer(); } Loading Loading
api/test-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -4031,6 +4031,8 @@ package android.app { method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect); method public android.app.ActivityOptions setLaunchDisplayId(int); method public void setLaunchStackId(int); method public void setLaunchTaskId(int); method public void setTaskOverlay(boolean, boolean); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
core/java/android/app/ActivityOptions.java +2 −0 Original line number Diff line number Diff line Loading @@ -1068,6 +1068,7 @@ public class ActivityOptions { * Sets the task the activity will be launched in. * @hide */ @TestApi public void setLaunchTaskId(int taskId) { mLaunchTaskId = taskId; } Loading @@ -1085,6 +1086,7 @@ public class ActivityOptions { * the task will also not be moved to the front of the stack. * @hide */ @TestApi public void setTaskOverlay(boolean taskOverlay, boolean canResume) { mTaskOverlay = taskOverlay; mTaskOverlayCanResume = canResume; Loading
packages/Shell/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ <uses-permission android:name="android.permission.GET_APP_OPS_STATS" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> <uses-permission android:name="android.permission.MANAGE_AUTO_FILL" /> Loading
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +18 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,8 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.view.Display.INVALID_DISPLAY; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; final class ActivityManagerShellCommand extends ShellCommand { public static final String NO_CLASS_ERROR_CODE = "Error type 3"; private static final String SHELL_PACKAGE_NAME = "com.android.shell"; Loading Loading @@ -118,6 +120,8 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mStreaming; // Streaming the profiling output to a file. private int mDisplayId; private int mStackId; private int mTaskId; private boolean mIsTaskOverlay; final boolean mDumping; Loading Loading @@ -263,6 +267,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mUserId = defUser; mDisplayId = INVALID_DISPLAY; mStackId = INVALID_STACK_ID; mTaskId = INVALID_TASK_ID; mIsTaskOverlay = false; return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { @Override Loading Loading @@ -297,6 +303,10 @@ final class ActivityManagerShellCommand extends ShellCommand { mDisplayId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--stack")) { mStackId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--task")) { mTaskId = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--task-overlay")) { mIsTaskOverlay = true; } else { return false; } Loading Loading @@ -380,6 +390,14 @@ final class ActivityManagerShellCommand extends ShellCommand { options = ActivityOptions.makeBasic(); options.setLaunchStackId(mStackId); } if (mTaskId != INVALID_TASK_ID) { options = ActivityOptions.makeBasic(); options.setLaunchTaskId(mTaskId); if (mIsTaskOverlay) { options.setTaskOverlay(true, true /* canResume */); } } if (mWaitOption) { result = mInterface.startActivityAndWait(null, null, intent, mimeType, null, null, 0, mStartFlags, profilerInfo, Loading
services/core/java/com/android/server/am/ActivityStack.java +70 −27 Original line number Diff line number Diff line Loading @@ -67,7 +67,9 @@ import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; import static com.android.server.am.ActivityStackSupervisor.ON_TOP; import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE; import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; import static com.android.server.wm.AppTransition.TRANSIT_NONE; Loading Loading @@ -121,7 +123,6 @@ import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityStackSupervisor.ActivityContainer; import com.android.server.wm.StackWindowController; import com.android.server.wm.StackWindowListener; import com.android.server.wm.TaskStack; import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; Loading Loading @@ -1185,13 +1186,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * @param resuming The activity we are currently trying to resume or null if this is not being * called as part of resuming the top activity, so we shouldn't try to instigate * a resume here if not null. * @param dontWait True if the caller does not want to wait for the pause to complete. If * set to true, we will immediately complete the pause here before returning. * @param pauseImmediately True if the caller does not want to wait for the activity callback to * complete pausing. * @return Returns true if an activity now is in the PAUSING state, and we are waiting for * it to tell us when it is done. */ final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean dontWait) { ActivityRecord resuming, boolean pauseImmediately) { if (mPausingActivity != null) { Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + " state=" + mPausingActivity.state); Loading @@ -1213,7 +1214,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (mActivityContainer.mParentActivity == null) { // Top level stack, not a child. Look for child stacks. mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait); mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, pauseImmediately); } if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSING: " + prev); Loading Loading @@ -1243,7 +1245,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai prev.shortComponentName); mService.updateUsageStats(prev, false); prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); userLeaving, prev.configChangeFlags, pauseImmediately); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. Slog.w(TAG, "Exception thrown during pause", e); Loading Loading @@ -1274,7 +1276,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off"); } if (dontWait) { if (pauseImmediately) { // If the caller said they don't want to wait for the pause, then complete // the pause now. completePauseLocked(false, resuming); Loading Loading @@ -3487,12 +3489,20 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.icicle = null; } /** * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)} */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY); } /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { String reason, boolean oomAdj, boolean pauseImmediately) { if (r.finishing) { Slog.w(TAG, "Duplicate finish request for " + r); return false; Loading Loading @@ -3530,7 +3540,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + r); if (endTask) { mService.mTaskChangeNotificationController.notifyTaskRemovalStarted(task.taskId); mService.mTaskChangeNotificationController.notifyTaskRemovalStarted( task.taskId); } mWindowManager.prepareAppTransition(transit, false); Loading @@ -3541,7 +3552,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r); if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false"); startPausingLocked(false, false, null, false); startPausingLocked(false, false, null, pauseImmediately); } if (endTask) { Loading @@ -3552,15 +3563,30 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // it is done pausing; else we can just directly finish it here. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r); if (r.visible) { mWindowManager.prepareAppTransition(transit, false); r.setVisibility(false); mWindowManager.executeAppTransition(); if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { mStackSupervisor.mWaitingVisibleActivities.add(r); prepareActivityHideTransitionAnimation(r, transit); } final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE; final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj) == null; // The following code is an optimization. When the last non-task overlay activity // is removed from the task, we remove the entire task from the stack. However, // since that is done after the scheduled destroy callback from the activity, that // call to change the visibility of the task overlay activities would be out of // sync with the activitiy visibility being set for this finishing activity above. // In this case, we can set the visibility of all the task overlay activities when // we detect the last one is finishing to keep them in sync. if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) { for (ActivityRecord taskOverlay : task.mActivities) { if (!taskOverlay.mTaskOverlay) { continue; } prepareActivityHideTransitionAnimation(taskOverlay, transit); } } return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null; return removedActivity; } else { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r); } Loading @@ -3571,6 +3597,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) { mWindowManager.prepareAppTransition(transit, false); r.setVisibility(false); mWindowManager.executeAppTransition(); if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) { mStackSupervisor.mWaitingVisibleActivities.add(r); } } static final int FINISH_IMMEDIATELY = 0; static final int FINISH_AFTER_PAUSE = 1; static final int FINISH_AFTER_VISIBLE = 2; Loading Loading @@ -3864,15 +3899,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.removeWindowContainer(); final TaskRecord task = r.task; final boolean lastActivity = task != null ? task.removeActivity(r) : false; // If we are removing the last activity in the task, not including task overlay activities, // then fall through into the block below to remove the entire task itself final boolean onlyHasTaskOverlays = task != null ? task.onlyHasTaskOverlayActivities(false /* excludingFinishing */) : false; if (lastActivity || onlyHasTaskOverlays) { if (DEBUG_STACK) { Slog.i(TAG_STACK, "removeActivityFromHistoryLocked: last activity removed from " + this + " onlyHasTaskOverlays=" + onlyHasTaskOverlays); } if (lastActivity) { if (DEBUG_STACK) Slog.i(TAG_STACK, "removeActivityFromHistoryLocked: last activity removed from " + this); if (mStackSupervisor.isFocusedStack(this) && task == topTask() && task.isOverHomeStack()) { mStackSupervisor.moveHomeStackTaskToTop(reason); } removeTask(task, reason); removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } cleanUpActivityServicesLocked(r); r.removeUriPermissionsLocked(); Loading Loading @@ -4923,10 +4966,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return starting; } void removeTask(TaskRecord task, String reason) { removeTask(task, reason, REMOVE_TASK_MODE_DESTROYING); } /** * Removes the input task from this stack. * @param task to remove. Loading @@ -4936,6 +4975,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai */ void removeTask(TaskRecord task, String reason, int mode) { if (mode == REMOVE_TASK_MODE_DESTROYING) { // When destroying a task, tell the supervisor to remove it so that any activity it has // can be cleaned up correctly mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */, !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY); task.removeWindowContainer(); } Loading