Loading services/core/java/com/android/server/wm/ActivityRecord.java +12 −30 Original line number Diff line number Diff line Loading @@ -2444,20 +2444,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } private void removeAppTokenFromDisplay() { if (mWmService.mRoot == null) return; final DisplayContent dc = mWmService.mRoot.getDisplayContent(getDisplayId()); if (dc == null) { Slog.w(TAG, "removeAppTokenFromDisplay: Attempted to remove token: " + appToken + " from non-existing displayId=" + getDisplayId()); return; } // Resume key dispatching if it is currently paused before we remove the container. resumeKeyDispatchingLocked(); dc.removeAppToken(appToken.asBinder()); } /** * Reparents this activity into {@param newTaskFrag} at the provided {@param position}. The * caller should ensure that the {@param newTaskFrag} is not already the parent of this Loading Loading @@ -3008,7 +2994,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @interface FinishRequest {} /** * See {@link #finishIfPossible(int, Intent, String, boolean)} * See {@link #finishIfPossible(int, Intent, NeededUriGrants, String, boolean)} */ @FinishRequest int finishIfPossible(String reason, boolean oomAdj) { return finishIfPossible(Activity.RESULT_CANCELED, Loading Loading @@ -3470,7 +3456,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setState(DESTROYED, "removeFromHistory"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this); detachFromProcess(); removeAppTokenFromDisplay(); // Resume key dispatching if it is currently paused before we remove the container. resumeKeyDispatchingLocked(); mDisplayContent.removeAppToken(appToken); cleanUpActivityServices(); removeUriPermissionsLocked(); Loading Loading @@ -3687,12 +3675,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Override void removeImmediately() { if (!isState(DESTROYING, DESTROYED)) { if (mState != DESTROYED) { Slog.w(TAG, "Force remove immediately " + this + " state=" + mState); // If Task#removeImmediately is called directly with alive activities, ensure that the // activities are destroyed and detached from process. destroyImmediately("removeImmediately"); } // Complete the destruction immediately because this activity will not be found in // hierarchy, it is unable to report completion. destroyed("removeImmediately"); } else { onRemovedFromDisplay(); } super.removeImmediately(); } Loading Loading @@ -6624,17 +6617,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } boolean hasWindowsAlive() { for (int i = mChildren.size() - 1; i >= 0; i--) { // No need to loop through child windows as the answer should be the same as that of the // parent window. if (!(mChildren.get(i)).mAppDied) { return true; } } return false; } void setWillReplaceWindows(boolean animate) { ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Marking app token %s with replacing windows.", this); Loading services/core/java/com/android/server/wm/Task.java +11 −57 Original line number Diff line number Diff line Loading @@ -125,7 +125,6 @@ import static com.android.server.wm.TaskProto.SURFACE_HEIGHT; import static com.android.server.wm.TaskProto.SURFACE_WIDTH; import static com.android.server.wm.TaskProto.TASK_FRAGMENT; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; Loading Loading @@ -1513,7 +1512,7 @@ class Task extends TaskFragment { if (DEBUG_TASK_MOVEMENT) { Slog.d(TAG_WM, "removeChild: child=" + r + " reason=" + reason); } super.removeChild(r); super.removeChild(r, false /* removeSelfIfPossible */); if (inPinnedWindowingMode()) { // We normally notify listeners of task stack changes on pause, however root pinned task Loading Loading @@ -1543,7 +1542,10 @@ class Task extends TaskFragment { // Remove entire task if it doesn't have any activity left and it isn't marked for reuse // or created by task organizer. if (!isRootTask()) { getRootTask().removeChild(this, reason); final WindowContainer<?> parent = getParent(); if (parent != null) { parent.asTaskFragment().removeChild(this); } } EventLogTags.writeWmTaskRemoved(mTaskId, "removeChild:" + reason + " last r=" + r + " in t=" + this); Loading Loading @@ -2594,25 +2596,12 @@ class Task extends TaskFragment { } } @VisibleForTesting boolean hasWindowsAlive() { return getActivity(ActivityRecord::hasWindowsAlive) != null; } @VisibleForTesting boolean shouldDeferRemoval() { if (mChildren.isEmpty()) { // No reason to defer removal of a Task that doesn't have any child. return false; } return hasWindowsAlive() && getRootTask().isAnimating(TRANSITION | CHILDREN); } @Override void removeImmediately() { removeImmediately("removeTask"); } @Override void removeImmediately(String reason) { if (DEBUG_ROOT_TASK) Slog.i(TAG, "removeTask:" + reason + " removing taskId=" + mTaskId); if (mRemoving) { Loading Loading @@ -3393,19 +3382,9 @@ class Task extends TaskFragment { @Override void dump(PrintWriter pw, String prefix, boolean dumpAll) { super.dump(pw, prefix, dumpAll); pw.println(prefix + "bounds=" + getBounds().toShortString()); final String doublePrefix = prefix + " "; for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowContainer<?> child = mChildren.get(i); pw.println(prefix + "* " + child); // Only dump non-activity because full activity info is already printed by // RootWindowContainer#dumpActivities. if (child.asActivityRecord() == null) { child.dump(pw, doublePrefix, dumpAll); } } if (!mExitingActivities.isEmpty()) { final String doublePrefix = prefix + " "; pw.println(); pw.println(prefix + "Exiting application tokens:"); for (int i = mExitingActivities.size() - 1; i >= 0; i--) { Loading Loading @@ -5359,18 +5338,6 @@ class Task extends TaskFragment { return true; } /** Finish all activities in the root task without waiting. */ void finishAllActivitiesImmediately() { if (!hasChild()) { removeIfPossible("finishAllActivitiesImmediately"); return; } forAllActivities((r) -> { Slog.d(TAG, "finishAllActivitiesImmediatelyLocked: finishing " + r); r.destroyIfPossible("finishAllActivitiesImmediately"); }); } /** @return true if the root task behind this one is a standard activity type. */ private boolean inFrontOfStandardRootTask() { final TaskDisplayArea taskDisplayArea = getDisplayArea(); Loading Loading @@ -5766,17 +5733,14 @@ class Task extends TaskFragment { @Override void dumpInner(String prefix, PrintWriter pw, boolean dumpAll, String dumpPackage) { pw.print(prefix); pw.print("* "); pw.println(this); pw.println(prefix + " mBounds=" + getRequestedOverrideBounds()); pw.println(prefix + " mCreatedByOrganizer=" + mCreatedByOrganizer); super.dumpInner(prefix, pw, dumpAll, dumpPackage); if (mCreatedByOrganizer) { pw.println(prefix + " mCreatedByOrganizer=true"); } if (mLastNonFullscreenBounds != null) { pw.print(prefix); pw.print(" mLastNonFullscreenBounds="); pw.println(mLastNonFullscreenBounds); } if (dumpAll) { printThisActivity(pw, mLastPausedActivity, dumpPackage, false, prefix + " mLastPausedActivity: ", null); } if (isLeafTask()) { pw.println(prefix + " isSleeping=" + shouldSleepActivities()); printThisActivity(pw, getTopPausingActivity(), dumpPackage, false, Loading Loading @@ -6173,16 +6137,6 @@ class Task extends TaskFragment { getDisplayContent().getPinnedTaskController().setActions(actions); } /** Returns true if a removal action is still being deferred. */ boolean handleCompleteDeferredRemoval() { if (isAnimating(TRANSITION | CHILDREN) || mAtmService.getTransitionController().inTransition(this)) { return true; } return super.handleCompleteDeferredRemoval(); } public DisplayInfo getDisplayInfo() { return mDisplayContent.getDisplayInfo(); } Loading services/core/java/com/android/server/wm/TaskDisplayArea.java +1 −1 Original line number Diff line number Diff line Loading @@ -2104,7 +2104,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { if (destroyContentOnRemoval || !task.isActivityTypeStandardOrUndefined() || task.mCreatedByOrganizer) { task.finishAllActivitiesImmediately(); task.remove(false /* withTransition */, "removeTaskDisplayArea"); } else { // Reparent task to corresponding launch root or display area. final WindowContainer launchRoot = Loading services/core/java/com/android/server/wm/TaskFragment.java +85 −9 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ import static com.android.server.wm.TaskFragmentProto.DISPLAY_ID; import static com.android.server.wm.TaskFragmentProto.MIN_HEIGHT; import static com.android.server.wm.TaskFragmentProto.MIN_WIDTH; import static com.android.server.wm.TaskFragmentProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK_FRAGMENT; import android.annotation.IntDef; Loading Loading @@ -158,8 +160,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { */ int mMinHeight; /** Avoid reentrant of {@link #removeImmediately()}. */ private boolean mRemoving; /** This task fragment will be removed when the cleanup of its children are done. */ private boolean mIsRemovalRequested; /** The TaskFragment that is adjacent to this one. */ @Nullable Loading Loading @@ -2047,15 +2049,67 @@ class TaskFragment extends WindowContainer<WindowContainer> { } @Override void removeImmediately() { if (mRemoving) { void removeChild(WindowContainer child) { removeChild(child, true /* removeSelfIfPossible */); } void removeChild(WindowContainer child, boolean removeSelfIfPossible) { super.removeChild(child); if (removeSelfIfPossible && (!mCreatedByOrganizer || mIsRemovalRequested) && !hasChild()) { removeImmediately("removeLastChild " + child); } } /** * Requests to remove this task fragment. If it doesn't have children, it is removed * immediately. Otherwise it will be removed until all activities are destroyed. * * @param withTransition Whether to use transition animation when removing activities. Set to * {@code false} if this is invisible to user, e.g. display removal. */ void remove(boolean withTransition, String reason) { if (!hasChild()) { removeImmediately(reason); return; } mRemoving = true; mIsRemovalRequested = true; forAllActivities(r -> { if (withTransition) { r.finishIfPossible(reason, false /* oomAdj */); } else { r.destroyIfPossible(reason); } }); } boolean shouldDeferRemoval() { if (!hasChild()) { return false; } return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES) || mAtmService.getTransitionController().inTransition(this); } @Override boolean handleCompleteDeferredRemoval() { if (shouldDeferRemoval()) { return true; } return super.handleCompleteDeferredRemoval(); } /** The overridden method must call {@link #removeImmediately()} instead of super. */ void removeImmediately(String reason) { Slog.d(TAG, "Remove task fragment: " + reason); removeImmediately(); } @Override void removeImmediately() { mIsRemovalRequested = false; resetAdjacentTaskFragment(); super.removeImmediately(); sendTaskFragmentVanished(); mRemoving = false; } boolean dump(String prefix, FileDescriptor fd, PrintWriter pw, boolean dumpAll, Loading Loading @@ -2097,13 +2151,35 @@ class TaskFragment extends WindowContainer<WindowContainer> { void dumpInner(String prefix, PrintWriter pw, boolean dumpAll, String dumpPackage) { pw.print(prefix); pw.print("* "); pw.println(this); pw.println(prefix + " mBounds=" + getRequestedOverrideBounds()); final Rect bounds = getRequestedOverrideBounds(); if (!bounds.isEmpty()) { pw.println(prefix + " mBounds=" + bounds); } if (mIsRemovalRequested) { pw.println(prefix + " mIsRemovalRequested=true"); } if (dumpAll) { printThisActivity(pw, mLastPausedActivity, dumpPackage, false, prefix + " mLastPausedActivity: ", null); } } @Override void dump(PrintWriter pw, String prefix, boolean dumpAll) { super.dump(pw, prefix, dumpAll); pw.println(prefix + "bounds=" + getBounds().toShortString()); final String doublePrefix = prefix + " "; for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowContainer<?> child = mChildren.get(i); pw.println(prefix + "* " + child); // Only dump non-activity because full activity info is already printed by // RootWindowContainer#dumpActivities. if (child.asActivityRecord() == null) { child.dump(pw, doublePrefix, dumpAll); } } } @Override void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); Loading services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +10 −5 Original line number Diff line number Diff line Loading @@ -230,12 +230,17 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr validateAndGetState(organizer); final int pid = Binder.getCallingPid(); final long uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Unregister task fragment organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); removeOrganizer(organizer); } } finally { Binder.restoreCallingIdentity(origId); } } void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) { Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +12 −30 Original line number Diff line number Diff line Loading @@ -2444,20 +2444,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } private void removeAppTokenFromDisplay() { if (mWmService.mRoot == null) return; final DisplayContent dc = mWmService.mRoot.getDisplayContent(getDisplayId()); if (dc == null) { Slog.w(TAG, "removeAppTokenFromDisplay: Attempted to remove token: " + appToken + " from non-existing displayId=" + getDisplayId()); return; } // Resume key dispatching if it is currently paused before we remove the container. resumeKeyDispatchingLocked(); dc.removeAppToken(appToken.asBinder()); } /** * Reparents this activity into {@param newTaskFrag} at the provided {@param position}. The * caller should ensure that the {@param newTaskFrag} is not already the parent of this Loading Loading @@ -3008,7 +2994,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @interface FinishRequest {} /** * See {@link #finishIfPossible(int, Intent, String, boolean)} * See {@link #finishIfPossible(int, Intent, NeededUriGrants, String, boolean)} */ @FinishRequest int finishIfPossible(String reason, boolean oomAdj) { return finishIfPossible(Activity.RESULT_CANCELED, Loading Loading @@ -3470,7 +3456,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setState(DESTROYED, "removeFromHistory"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this); detachFromProcess(); removeAppTokenFromDisplay(); // Resume key dispatching if it is currently paused before we remove the container. resumeKeyDispatchingLocked(); mDisplayContent.removeAppToken(appToken); cleanUpActivityServices(); removeUriPermissionsLocked(); Loading Loading @@ -3687,12 +3675,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Override void removeImmediately() { if (!isState(DESTROYING, DESTROYED)) { if (mState != DESTROYED) { Slog.w(TAG, "Force remove immediately " + this + " state=" + mState); // If Task#removeImmediately is called directly with alive activities, ensure that the // activities are destroyed and detached from process. destroyImmediately("removeImmediately"); } // Complete the destruction immediately because this activity will not be found in // hierarchy, it is unable to report completion. destroyed("removeImmediately"); } else { onRemovedFromDisplay(); } super.removeImmediately(); } Loading Loading @@ -6624,17 +6617,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } boolean hasWindowsAlive() { for (int i = mChildren.size() - 1; i >= 0; i--) { // No need to loop through child windows as the answer should be the same as that of the // parent window. if (!(mChildren.get(i)).mAppDied) { return true; } } return false; } void setWillReplaceWindows(boolean animate) { ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Marking app token %s with replacing windows.", this); Loading
services/core/java/com/android/server/wm/Task.java +11 −57 Original line number Diff line number Diff line Loading @@ -125,7 +125,6 @@ import static com.android.server.wm.TaskProto.SURFACE_HEIGHT; import static com.android.server.wm.TaskProto.SURFACE_WIDTH; import static com.android.server.wm.TaskProto.TASK_FRAGMENT; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; Loading Loading @@ -1513,7 +1512,7 @@ class Task extends TaskFragment { if (DEBUG_TASK_MOVEMENT) { Slog.d(TAG_WM, "removeChild: child=" + r + " reason=" + reason); } super.removeChild(r); super.removeChild(r, false /* removeSelfIfPossible */); if (inPinnedWindowingMode()) { // We normally notify listeners of task stack changes on pause, however root pinned task Loading Loading @@ -1543,7 +1542,10 @@ class Task extends TaskFragment { // Remove entire task if it doesn't have any activity left and it isn't marked for reuse // or created by task organizer. if (!isRootTask()) { getRootTask().removeChild(this, reason); final WindowContainer<?> parent = getParent(); if (parent != null) { parent.asTaskFragment().removeChild(this); } } EventLogTags.writeWmTaskRemoved(mTaskId, "removeChild:" + reason + " last r=" + r + " in t=" + this); Loading Loading @@ -2594,25 +2596,12 @@ class Task extends TaskFragment { } } @VisibleForTesting boolean hasWindowsAlive() { return getActivity(ActivityRecord::hasWindowsAlive) != null; } @VisibleForTesting boolean shouldDeferRemoval() { if (mChildren.isEmpty()) { // No reason to defer removal of a Task that doesn't have any child. return false; } return hasWindowsAlive() && getRootTask().isAnimating(TRANSITION | CHILDREN); } @Override void removeImmediately() { removeImmediately("removeTask"); } @Override void removeImmediately(String reason) { if (DEBUG_ROOT_TASK) Slog.i(TAG, "removeTask:" + reason + " removing taskId=" + mTaskId); if (mRemoving) { Loading Loading @@ -3393,19 +3382,9 @@ class Task extends TaskFragment { @Override void dump(PrintWriter pw, String prefix, boolean dumpAll) { super.dump(pw, prefix, dumpAll); pw.println(prefix + "bounds=" + getBounds().toShortString()); final String doublePrefix = prefix + " "; for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowContainer<?> child = mChildren.get(i); pw.println(prefix + "* " + child); // Only dump non-activity because full activity info is already printed by // RootWindowContainer#dumpActivities. if (child.asActivityRecord() == null) { child.dump(pw, doublePrefix, dumpAll); } } if (!mExitingActivities.isEmpty()) { final String doublePrefix = prefix + " "; pw.println(); pw.println(prefix + "Exiting application tokens:"); for (int i = mExitingActivities.size() - 1; i >= 0; i--) { Loading Loading @@ -5359,18 +5338,6 @@ class Task extends TaskFragment { return true; } /** Finish all activities in the root task without waiting. */ void finishAllActivitiesImmediately() { if (!hasChild()) { removeIfPossible("finishAllActivitiesImmediately"); return; } forAllActivities((r) -> { Slog.d(TAG, "finishAllActivitiesImmediatelyLocked: finishing " + r); r.destroyIfPossible("finishAllActivitiesImmediately"); }); } /** @return true if the root task behind this one is a standard activity type. */ private boolean inFrontOfStandardRootTask() { final TaskDisplayArea taskDisplayArea = getDisplayArea(); Loading Loading @@ -5766,17 +5733,14 @@ class Task extends TaskFragment { @Override void dumpInner(String prefix, PrintWriter pw, boolean dumpAll, String dumpPackage) { pw.print(prefix); pw.print("* "); pw.println(this); pw.println(prefix + " mBounds=" + getRequestedOverrideBounds()); pw.println(prefix + " mCreatedByOrganizer=" + mCreatedByOrganizer); super.dumpInner(prefix, pw, dumpAll, dumpPackage); if (mCreatedByOrganizer) { pw.println(prefix + " mCreatedByOrganizer=true"); } if (mLastNonFullscreenBounds != null) { pw.print(prefix); pw.print(" mLastNonFullscreenBounds="); pw.println(mLastNonFullscreenBounds); } if (dumpAll) { printThisActivity(pw, mLastPausedActivity, dumpPackage, false, prefix + " mLastPausedActivity: ", null); } if (isLeafTask()) { pw.println(prefix + " isSleeping=" + shouldSleepActivities()); printThisActivity(pw, getTopPausingActivity(), dumpPackage, false, Loading Loading @@ -6173,16 +6137,6 @@ class Task extends TaskFragment { getDisplayContent().getPinnedTaskController().setActions(actions); } /** Returns true if a removal action is still being deferred. */ boolean handleCompleteDeferredRemoval() { if (isAnimating(TRANSITION | CHILDREN) || mAtmService.getTransitionController().inTransition(this)) { return true; } return super.handleCompleteDeferredRemoval(); } public DisplayInfo getDisplayInfo() { return mDisplayContent.getDisplayInfo(); } Loading
services/core/java/com/android/server/wm/TaskDisplayArea.java +1 −1 Original line number Diff line number Diff line Loading @@ -2104,7 +2104,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { if (destroyContentOnRemoval || !task.isActivityTypeStandardOrUndefined() || task.mCreatedByOrganizer) { task.finishAllActivitiesImmediately(); task.remove(false /* withTransition */, "removeTaskDisplayArea"); } else { // Reparent task to corresponding launch root or display area. final WindowContainer launchRoot = Loading
services/core/java/com/android/server/wm/TaskFragment.java +85 −9 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ import static com.android.server.wm.TaskFragmentProto.DISPLAY_ID; import static com.android.server.wm.TaskFragmentProto.MIN_HEIGHT; import static com.android.server.wm.TaskFragmentProto.MIN_WIDTH; import static com.android.server.wm.TaskFragmentProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK_FRAGMENT; import android.annotation.IntDef; Loading Loading @@ -158,8 +160,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { */ int mMinHeight; /** Avoid reentrant of {@link #removeImmediately()}. */ private boolean mRemoving; /** This task fragment will be removed when the cleanup of its children are done. */ private boolean mIsRemovalRequested; /** The TaskFragment that is adjacent to this one. */ @Nullable Loading Loading @@ -2047,15 +2049,67 @@ class TaskFragment extends WindowContainer<WindowContainer> { } @Override void removeImmediately() { if (mRemoving) { void removeChild(WindowContainer child) { removeChild(child, true /* removeSelfIfPossible */); } void removeChild(WindowContainer child, boolean removeSelfIfPossible) { super.removeChild(child); if (removeSelfIfPossible && (!mCreatedByOrganizer || mIsRemovalRequested) && !hasChild()) { removeImmediately("removeLastChild " + child); } } /** * Requests to remove this task fragment. If it doesn't have children, it is removed * immediately. Otherwise it will be removed until all activities are destroyed. * * @param withTransition Whether to use transition animation when removing activities. Set to * {@code false} if this is invisible to user, e.g. display removal. */ void remove(boolean withTransition, String reason) { if (!hasChild()) { removeImmediately(reason); return; } mRemoving = true; mIsRemovalRequested = true; forAllActivities(r -> { if (withTransition) { r.finishIfPossible(reason, false /* oomAdj */); } else { r.destroyIfPossible(reason); } }); } boolean shouldDeferRemoval() { if (!hasChild()) { return false; } return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES) || mAtmService.getTransitionController().inTransition(this); } @Override boolean handleCompleteDeferredRemoval() { if (shouldDeferRemoval()) { return true; } return super.handleCompleteDeferredRemoval(); } /** The overridden method must call {@link #removeImmediately()} instead of super. */ void removeImmediately(String reason) { Slog.d(TAG, "Remove task fragment: " + reason); removeImmediately(); } @Override void removeImmediately() { mIsRemovalRequested = false; resetAdjacentTaskFragment(); super.removeImmediately(); sendTaskFragmentVanished(); mRemoving = false; } boolean dump(String prefix, FileDescriptor fd, PrintWriter pw, boolean dumpAll, Loading Loading @@ -2097,13 +2151,35 @@ class TaskFragment extends WindowContainer<WindowContainer> { void dumpInner(String prefix, PrintWriter pw, boolean dumpAll, String dumpPackage) { pw.print(prefix); pw.print("* "); pw.println(this); pw.println(prefix + " mBounds=" + getRequestedOverrideBounds()); final Rect bounds = getRequestedOverrideBounds(); if (!bounds.isEmpty()) { pw.println(prefix + " mBounds=" + bounds); } if (mIsRemovalRequested) { pw.println(prefix + " mIsRemovalRequested=true"); } if (dumpAll) { printThisActivity(pw, mLastPausedActivity, dumpPackage, false, prefix + " mLastPausedActivity: ", null); } } @Override void dump(PrintWriter pw, String prefix, boolean dumpAll) { super.dump(pw, prefix, dumpAll); pw.println(prefix + "bounds=" + getBounds().toShortString()); final String doublePrefix = prefix + " "; for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowContainer<?> child = mChildren.get(i); pw.println(prefix + "* " + child); // Only dump non-activity because full activity info is already printed by // RootWindowContainer#dumpActivities. if (child.asActivityRecord() == null) { child.dump(pw, doublePrefix, dumpAll); } } } @Override void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); Loading
services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +10 −5 Original line number Diff line number Diff line Loading @@ -230,12 +230,17 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr validateAndGetState(organizer); final int pid = Binder.getCallingPid(); final long uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Unregister task fragment organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); removeOrganizer(organizer); } } finally { Binder.restoreCallingIdentity(origId); } } void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) { Loading