am c407ace3: am d4c819c0: am dd9ce628: Merge "Clean up activities and displays when done" into klp-modular-dev
* commit 'c407ace3019c4e542654cf17fd04d9436d3f3436':
Clean up activities and displays when done
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b40008e..04155b5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2038,6 +2038,15 @@
return true;
}
+ case DELETE_ACTIVITY_CONTAINER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IActivityContainer activityContainer =
+ IActivityContainer.Stub.asInterface(data.readStrongBinder());
+ deleteActivityContainer(activityContainer);
+ reply.writeNoException();
+ return true;
+ }
+
case GET_ACTIVITY_CONTAINER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder activityToken = data.readStrongBinder();
@@ -4697,6 +4706,18 @@
return res;
}
+ public void deleteActivityContainer(IActivityContainer activityContainer)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(activityContainer.asBinder());
+ mRemote.transact(DELETE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 14f0829..113f123 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -37,6 +37,7 @@
import android.view.ViewGroup;
import android.view.WindowManager;
+/** @hide */
public class ActivityView extends ViewGroup {
private final String TAG = "ActivityView";
private final boolean DEBUG = false;
@@ -107,6 +108,10 @@
super.onDetachedFromWindow();
if (mActivityContainer != null) {
detach();
+ try {
+ ActivityManagerNative.getDefault().deleteActivityContainer(mActivityContainer);
+ } catch (RemoteException e) {
+ }
mActivityContainer = null;
}
}
@@ -122,7 +127,6 @@
case View.INVISIBLE:
break;
case View.GONE:
- detach();
break;
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8c7fe10..bbf2ecc 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -408,9 +408,13 @@
public void performIdleMaintenance() throws RemoteException;
+ /** @hide */
public IActivityContainer createActivityContainer(IBinder parentActivityToken,
IActivityContainerCallback callback) throws RemoteException;
+ /** @hide */
+ public void deleteActivityContainer(IActivityContainer container) throws RemoteException;
+
public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
throws RemoteException;
@@ -704,4 +708,5 @@
int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
+ int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7b2fc50..d5c3cb4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7107,6 +7107,15 @@
}
@Override
+ public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
+ enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+ "deleteActivityContainer()");
+ synchronized (this) {
+ mStackSupervisor.deleteActivityContainer(container);
+ }
+ }
+
+ @Override
public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
throws RemoteException {
synchronized (this) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 3a837e8..8934852 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2180,13 +2180,28 @@
ActivityRecord top = stack.topRunningNonDelayedActivityLocked(null);
if (top != null) {
// TODO: Make sure the next activity doesn't start up when top is destroyed.
- stack.destroyActivityLocked(top, true, true, "stack removal");
+ stack.destroyActivityLocked(top, true, true, "stack parent destroyed");
}
mActivityContainers.removeAt(ndx);
container.detachLocked();
}
}
+ void deleteActivityContainer(IActivityContainer container) {
+ ActivityContainer activityContainer = (ActivityContainer)container;
+ if (activityContainer != null) {
+ activityContainer.mStack.destroyActivitiesLocked(null, true,
+ "deleteActivityContainer");
+ final ActivityRecord parent = activityContainer.mParentActivity;
+ if (parent != null) {
+ parent.mChildContainers.remove(activityContainer);
+ }
+ final int stackId = activityContainer.mStackId;
+ mActivityContainers.remove(stackId);
+ mWindowManager.removeStack(stackId);
+ }
+ }
+
private int createStackOnDisplay(ActivityRecord parentActivity, int stackId, int displayId) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
@@ -2557,6 +2572,7 @@
pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout);
pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
+ pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 68834d8..d4bcd5c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -102,9 +102,8 @@
final WindowManagerService mService;
- static final int DEFER_DETACH = 1;
- static final int DEFER_REMOVAL = 2;
- int mDeferredActions;
+ /** Remove this display when animation on it has completed. */
+ boolean mDeferredRemoval;
/**
* @param display May not be null.
@@ -302,6 +301,49 @@
}
}
+ boolean isAnimating() {
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ final TaskStack stack = mStacks.get(stackNdx);
+ if (stack.isAnimating()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void checkForDeferredActions() {
+ boolean animating = false;
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ final TaskStack stack = mStacks.get(stackNdx);
+ if (stack.isAnimating()) {
+ animating = true;
+ } else {
+ if (stack.mDeferDetach) {
+ mService.detachStackLocked(this, stack);
+ }
+ final ArrayList<Task> tasks = stack.getTasks();
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ final Task task = tasks.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);
+ }
+ }
+ }
+ }
+ if (!animating && mDeferredRemoval) {
+ mService.onDisplayRemoved(mDisplayId);
+ }
+ }
+
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
final String subPrefix = " " + prefix;
@@ -325,7 +367,8 @@
pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
- pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
+ pw.print(subPrefix); pw.print("deferred="); pw.print(mDeferredRemoval);
+ pw.print(" layoutNeeded="); pw.println(layoutNeeded);
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final TaskStack stack = mStacks.get(stackNdx);
pw.print(prefix); pw.print("mStacks[" + stackNdx + "]"); pw.println(stack.mStackId);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index c70bc62..81db8b3 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -75,6 +75,9 @@
/** Application tokens that are exiting, but still on screen for animations. */
final AppTokenList mExitingAppTokens = new AppTokenList();
+ /** Detach this stack from its display when animation completes. */
+ boolean mDeferDetach;
+
TaskStack(WindowManagerService service, int stackId) {
mService = service;
mStackId = stackId;
@@ -362,36 +365,9 @@
mAnimationBackgroundSurface.mDimSurface.destroy();
}
- void checkForDeferredActions() {
- if (mDisplayContent != null &&
- (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 &&
- !isAnimating()) {
- mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH;
- if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) {
- mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL;
- mService.onDisplayRemoved(mDisplayContent.getDisplayId());
- }
- mService.detachStack(mStackId);
- }
- 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) {
pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
+ pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
pw.print(prefix); pw.println(mTasks.get(taskNdx));
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f03f9a2..6e1724a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -188,6 +188,7 @@
static final boolean DEBUG_WINDOW_TRACE = false;
static final boolean DEBUG_TASK_MOVEMENT = false;
static final boolean DEBUG_STACK = false;
+ static final boolean DEBUG_DISPLAY = false;
static final boolean SHOW_SURFACE_ALLOC = false;
static final boolean SHOW_TRANSACTIONS = false;
static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -4929,6 +4930,11 @@
}
}
+ void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
+ displayContent.detachStack(stack);
+ stack.detachDisplay();
+ }
+
public void detachStack(int stackId) {
synchronized (mWindowMap) {
TaskStack stack = mStackIdToStack.get(stackId);
@@ -4936,16 +4942,19 @@
final DisplayContent displayContent = stack.getDisplayContent();
if (displayContent != null) {
if (stack.isAnimating()) {
- displayContent.mDeferredActions |= DisplayContent.DEFER_DETACH;
+ stack.mDeferDetach = true;
return;
}
- displayContent.detachStack(stack);
- stack.detachDisplay();
+ detachStackLocked(displayContent, stack);
}
}
}
}
+ public void removeStack(int stackId) {
+ mStackIdToStack.remove(stackId);
+ }
+
void removeTaskLocked(Task task) {
final int taskId = task.taskId;
final TaskStack stack = task.mStack;
@@ -9501,9 +9510,9 @@
}
}
- // Remove all deferred Stacks, tasks, and activities.
- for (int stackNdx = mPendingStacksRemove.size() - 1; stackNdx >= 0; --stackNdx) {
- mPendingStacksRemove.removeAt(stackNdx).checkForDeferredActions();
+ // Remove all deferred displays stacks, tasks, and activities.
+ for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+ mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
}
setFocusedStackFrame();
@@ -10788,6 +10797,7 @@
private DisplayContent newDisplayContentLocked(final Display display) {
DisplayContent displayContent = new DisplayContent(display, this);
final int displayId = display.getDisplayId();
+ if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display);
mDisplayContents.put(displayId, displayContent);
DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -10889,10 +10899,11 @@
private void handleDisplayRemovedLocked(int displayId) {
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent != null) {
- if ((displayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0) {
- displayContent.mDeferredActions |= DisplayContent.DEFER_REMOVAL;
+ if (displayContent.isAnimating()) {
+ displayContent.mDeferredRemoval = true;
return;
}
+ if (DEBUG_DISPLAY) Slog.v(TAG, "Removing display=" + displayContent);
mDisplayContents.delete(displayId);
displayContent.close();
if (displayId == Display.DEFAULT_DISPLAY) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index f98b724..93f6d22 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -430,7 +430,6 @@
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
- mService.mPendingStacksRemove.add(mWin.getStack());
mAnimator.hideWallpapersLocked(mWin);
}