summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Craig Mautner <cmautner@google.com> 2014-02-07 13:11:47 -0800
committer Craig Mautner <cmautner@google.com> 2014-02-07 13:11:47 -0800
commit9ef471f7f2f59de032d7cb9c3c7241486109979e (patch)
tree2eb6924aef35205a1715e02f168bcb5f2dedd9ba
parent8ff1f285c93a1a44a7419ab216bee2f92518387a (diff)
Don't remove Activities and Tasks until animation done
Just like stacks and displays, activities and tasks need to stick around until animations have completed. Change-Id: I54fe8f6855d60cbc3a25cbc6e762defd5ac50bf5
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java10
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java2
-rw-r--r--services/core/java/com/android/server/wm/Task.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java48
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java2
6 files changed, 63 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a7442c65db74..f609e7e6dfca 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1150,7 +1150,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
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;
@@ -3068,10 +3072,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
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 e98014bdea3e..ca4ad8a32e0d 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 @@ class AppWindowToken extends WindowToken {
// 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 9f7266349c04..036804c55b7d 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -25,6 +25,7 @@ class Task {
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 0941c7685502..7d8cff4a8040 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 @@ public class TaskStack {
mAnimationBackgroundSurface.mDimSurface.destroy();
}
- void checkForDeferredDetach() {
+ void checkForDeferredActions() {
if (mDisplayContent != null &&
(mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
!isAnimating()) {
@@ -377,6 +377,21 @@ public class TaskStack {
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 94f998c0048d..cf249ddc97f4 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.WindowManager.LayoutParams.*;
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;
@@ -366,6 +367,11 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
final Task oldTask = mTaskIdToTask.get(atoken.groupId);
- removeAppFromTask(atoken);
+ removeAppFromTaskLocked(atoken);
atoken.groupId = groupId;
Task newTask = mTaskIdToTask.get(groupId);
@@ -4517,11 +4525,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- 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);
}
}
@@ -4563,17 +4570,18 @@ public class WindowManagerService extends IWindowManager.Stub
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) {
@@ -4928,6 +4936,21 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ 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);
@@ -4935,14 +4958,14 @@ public class WindowManagerService extends IWindowManager.Stub
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;
@@ -9367,7 +9390,7 @@ public class WindowManagerService extends IWindowManager.Stub
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);
}
}
@@ -9460,6 +9483,11 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ // 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 5cff3197a336..ffb17f1fb374 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 @@ class WindowStateAnimator {
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
- mWin.getStack().checkForDeferredDetach();
+ mService.mPendingStacksRemove.add(mWin.getStack());
mAnimator.hideWallpapersLocked(mWin);
}