Merge "Clean up activities and displays when done" into klp-modular-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
dd9ce6287e
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -430,7 +430,6 @@ class WindowStateAnimator {
|
||||
mService.mPendingRemove.add(mWin);
|
||||
mWin.mRemoveOnExit = false;
|
||||
}
|
||||
mService.mPendingStacksRemove.add(mWin.getStack());
|
||||
mAnimator.hideWallpapersLocked(mWin);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user