Merge "Clean up activities and displays when done" into klp-modular-dev

This commit is contained in:
Craig Mautner
2014-02-25 18:46:01 +00:00
committed by Android (Google) Code Review
9 changed files with 127 additions and 43 deletions

View File

@ -2036,6 +2036,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
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();
@ -4692,6 +4701,18 @@ class ActivityManagerProxy implements IActivityManager
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();

View File

@ -37,6 +37,7 @@ import android.view.View;
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 @@ public class ActivityView extends ViewGroup {
super.onDetachedFromWindow();
if (mActivityContainer != null) {
detach();
try {
ActivityManagerNative.getDefault().deleteActivityContainer(mActivityContainer);
} catch (RemoteException e) {
}
mActivityContainer = null;
}
}
@ -122,7 +127,6 @@ public class ActivityView extends ViewGroup {
case View.INVISIBLE:
break;
case View.GONE:
detach();
break;
}
}

View File

@ -407,9 +407,13 @@ public interface IActivityManager extends IInterface {
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;
@ -703,4 +707,5 @@ public interface IActivityManager extends IInterface {
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;
}

View File

@ -7081,6 +7081,15 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
@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 {

View File

@ -2179,13 +2179,28 @@ public final class ActivityStackSupervisor implements DisplayListener {
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) {
@ -2556,6 +2571,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
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) {

View File

@ -102,9 +102,8 @@ class DisplayContent {
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 @@ class DisplayContent {
}
}
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 @@ class DisplayContent {
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);

View File

@ -75,6 +75,9 @@ public class TaskStack {
/** 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 @@ public class TaskStack {
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));
}

View File

@ -188,6 +188,7 @@ public class WindowManagerService extends IWindowManager.Stub
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;
@ -4931,6 +4932,11 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
displayContent.detachStack(stack);
stack.detachDisplay();
}
public void detachStack(int stackId) {
synchronized (mWindowMap) {
TaskStack stack = mStackIdToStack.get(stackId);
@ -4938,16 +4944,19 @@ public class WindowManagerService extends IWindowManager.Stub
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;
@ -9499,9 +9508,9 @@ 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();
// Remove all deferred displays stacks, tasks, and activities.
for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
}
setFocusedStackFrame();
@ -10780,6 +10789,7 @@ public class WindowManagerService extends IWindowManager.Stub
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();
@ -10881,10 +10891,11 @@ public class WindowManagerService extends IWindowManager.Stub
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) {

View File

@ -430,7 +430,6 @@ class WindowStateAnimator {
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
mService.mPendingStacksRemove.add(mWin.getStack());
mAnimator.hideWallpapersLocked(mWin);
}