am 779d204a: am 9ef471f7: Don\'t remove Activities and Tasks until animation done
* commit '779d204abe6a3922b572822df5cd775ffd5d77e8':
Don't remove Activities and Tasks until animation done
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a33b0e5..8f8b2a2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1151,7 +1151,11 @@
if (err == ActivityManager.START_SUCCESS) {
final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
- + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
+ + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)
+ + " on display " + (container == null ? (mFocusedStack == null ?
+ Display.DEFAULT_DISPLAY : mFocusedStack.mDisplayId) :
+ (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
+ container.mActivityDisplay.mDisplayId)));
}
ActivityRecord sourceRecord = null;
@@ -3069,10 +3073,6 @@
init(mDisplayManager.getDisplay(displayId));
}
- ActivityDisplay(Display display) {
- init(display);
- }
-
ActivityDisplay(Surface surface, int width, int height, int density) {
DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index e98014b..ca4ad8a 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -105,6 +105,8 @@
// Input application handle used by the input dispatcher.
final InputApplicationHandle mInputApplicationHandle;
+ boolean mDeferRemoval;
+
AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
super(_service, _token.asBinder(),
WindowManager.LayoutParams.TYPE_APPLICATION, true);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 44f2596..c301ffe 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -24,6 +24,7 @@
final AppTokenList mAppTokens = new AppTokenList();
final int taskId;
final int mUserId;
+ boolean mDeferRemoval = false;
Task(AppWindowToken wtoken, TaskStack stack, int userId) {
taskId = wtoken.groupId;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 0941c76..7d8cff4 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -366,7 +366,7 @@
mAnimationBackgroundSurface.mDimSurface.destroy();
}
- void checkForDeferredDetach() {
+ void checkForDeferredActions() {
if (mDisplayContent != null &&
(mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
!isAnimating()) {
@@ -377,6 +377,21 @@
mService.onDisplayRemoved(mDisplayContent.getDisplayId());
}
}
+ for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = mTasks.get(taskNdx);
+ AppTokenList tokens = task.mAppTokens;
+ for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+ AppWindowToken wtoken = tokens.get(tokenNdx);
+ if (wtoken.mDeferRemoval) {
+ wtoken.mDeferRemoval = false;
+ mService.removeAppFromTaskLocked(wtoken);
+ }
+ }
+ if (task.mDeferRemoval) {
+ task.mDeferRemoval = false;
+ mService.removeTaskLocked(task);
+ }
+ }
}
public void dump(String prefix, PrintWriter pw) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b76ec4b..7293d6f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -21,6 +21,7 @@
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import android.app.AppOpsManager;
+import android.util.ArraySet;
import android.util.TimeUtils;
import android.view.IWindowId;
@@ -363,6 +364,11 @@
final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
/**
+ * Stacks whose animations have ended and whose tasks, apps, selves may now be removed.
+ */
+ final ArraySet<TaskStack> mPendingStacksRemove = new ArraySet<TaskStack>();
+
+ /**
* Used when processing mPendingRemove to avoid working on the original array.
*/
WindowState[] mPendingRemoveTmp = new WindowState[20];
@@ -3425,6 +3431,8 @@
}
private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) {
+ if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId
+ + " atoken=" + atoken);
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
@@ -3507,7 +3515,7 @@
return;
}
final Task oldTask = mTaskIdToTask.get(atoken.groupId);
- removeAppFromTask(atoken);
+ removeAppFromTaskLocked(atoken);
atoken.groupId = groupId;
Task newTask = mTaskIdToTask.get(groupId);
@@ -4525,11 +4533,10 @@
}
}
- void removeAppFromTask(AppWindowToken wtoken) {
+ void removeAppFromTaskLocked(AppWindowToken wtoken) {
final Task task = mTaskIdToTask.get(wtoken.groupId);
- if (task != null && task.removeAppToken(wtoken)) {
- task.mStack.removeTask(task);
- mTaskIdToTask.delete(wtoken.groupId);
+ if (!wtoken.mDeferRemoval && task != null && task.removeAppToken(wtoken)) {
+ removeTaskLocked(task);
}
}
@@ -4571,17 +4578,18 @@
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"removeAppToken make exiting: " + wtoken);
stack.mExitingAppTokens.add(wtoken);
+ wtoken.mDeferRemoval = true;
} else {
// Make sure there is no animation running on this token,
// so any windows associated with it will be removed as
// soon as their animations are complete
wtoken.mAppAnimator.clearAnimation();
wtoken.mAppAnimator.animating = false;
+ removeAppFromTaskLocked(wtoken);
}
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"removeAppToken: " + wtoken);
- removeAppFromTask(wtoken);
wtoken.removed = true;
if (wtoken.startingData != null) {
@@ -4926,6 +4934,21 @@
}
}
+ void removeTaskLocked(Task task) {
+ final int taskId = task.taskId;
+ final TaskStack stack = task.mStack;
+ if (stack.isAnimating()) {
+ if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId);
+ task.mDeferRemoval = true;
+ return;
+ }
+ if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId);
+ EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
+ task.mDeferRemoval = false;
+ task.mStack.removeTask(task);
+ mTaskIdToTask.delete(task.taskId);
+ }
+
public void removeTask(int taskId) {
synchronized (mWindowMap) {
Task task = mTaskIdToTask.get(taskId);
@@ -4933,14 +4956,14 @@
if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
return;
}
- final TaskStack stack = task.mStack;
- EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
- stack.removeTask(task);
+ removeTaskLocked(task);
}
}
public void addTask(int taskId, int stackId, boolean toTop) {
synchronized (mWindowMap) {
+ if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId
+ + " to " + (toTop ? "top" : "bottom"));
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
return;
@@ -9365,7 +9388,7 @@
token.mAppAnimator.animating = false;
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
"performLayout: App token exiting now removed" + token);
- removeAppFromTask(token);
+ removeAppFromTaskLocked(token);
exitingAppTokens.remove(i);
}
}
@@ -9458,6 +9481,11 @@
}
}
+ // Remove all deferred Stacks, tasks, and activities.
+ for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) {
+ mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions();
+ }
+
setFocusedStackFrame();
// Check to see if we are now in a state where the screen should
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 5cff319..ffb17f1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -416,7 +416,7 @@
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
- mWin.getStack().checkForDeferredDetach();
+ mService.mPendingStacksRemove.add(mWin.getStack());
mAnimator.hideWallpapersLocked(mWin);
}