diff options
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 |
commit | 9ef471f7f2f59de032d7cb9c3c7241486109979e (patch) | |
tree | 2eb6924aef35205a1715e02f168bcb5f2dedd9ba /services/core/java | |
parent | 8ff1f285c93a1a44a7419ab216bee2f92518387a (diff) | |
download | frameworks_base-9ef471f7f2f59de032d7cb9c3c7241486109979e.zip frameworks_base-9ef471f7f2f59de032d7cb9c3c7241486109979e.tar.gz frameworks_base-9ef471f7f2f59de032d7cb9c3c7241486109979e.tar.bz2 |
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
Diffstat (limited to 'services/core/java')
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 a7442c6..f609e7e 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 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 @@ 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 9f72663..036804c 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 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 @@ 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 94f998c..cf249dd 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 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 @@ class WindowStateAnimator { mService.mPendingRemove.add(mWin); mWin.mRemoveOnExit = false; } - mWin.getStack().checkForDeferredDetach(); + mService.mPendingStacksRemove.add(mWin.getStack()); mAnimator.hideWallpapersLocked(mWin); } |