Loading services/core/java/com/android/server/wm/AppWindowToken.java +7 −11 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ class AppWindowToken extends WindowToken { final boolean voiceInteraction; Task mTask; // TODO: Have a fillParent variable in WindowContainer to this? boolean appFullscreen; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean layoutConfigChanges; Loading @@ -100,7 +101,7 @@ class AppWindowToken extends WindowToken { // These are to track the app's real drawing status if there were no saved surfaces. boolean allDrawnExcludingSaved; int numInterestingWindowsExcludingSaved; int numDrawnWindowsExclusingSaved; int numDrawnWindowsExcludingSaved; // Is this window's surface needed? This is almost like hidden, except // it will sometimes be true a little earlier: when the token has Loading Loading @@ -133,6 +134,7 @@ class AppWindowToken extends WindowToken { // Input application handle used by the input dispatcher. final InputApplicationHandle mInputApplicationHandle; // TODO: Have a WindowContainer state for tracking exiting/deferred removal. boolean mIsExiting; boolean mLaunchTaskBehind; Loading Loading @@ -356,18 +358,12 @@ class AppWindowToken extends WindowToken { return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable; } void removeAppFromTaskLocked() { @Override void removeIfPossible() { mIsExiting = false; removeAllWindows(); // Use local variable because removeAppToken will null out mTask. final Task task = mTask; if (task != null) { if (!task.removeAppToken(this)) { Slog.e(TAG, "removeAppFromTaskLocked: token=" + this + " not found."); } task.mStack.mExitingAppTokens.remove(this); if (mTask != null) { mTask.detachChild(this); } } Loading services/core/java/com/android/server/wm/DisplayContent.java +1 −1 Original line number Diff line number Diff line Loading @@ -515,7 +515,7 @@ class DisplayContent { for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { AppWindowToken wtoken = tokens.get(tokenNdx); if (wtoken.mIsExiting) { wtoken.removeAppFromTaskLocked(); wtoken.removeIfPossible(); } } } Loading services/core/java/com/android/server/wm/Task.java +8 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,14 @@ class Task implements DimLayer.DimLayerUser { } } // TODO: Don't forget to switch to WC.detachChild void detachChild(AppWindowToken wtoken) { if (!removeAppToken(wtoken)) { Slog.e(TAG, "detachChild: token=" + this + " not found."); } mStack.mExitingAppTokens.remove(wtoken); } boolean removeAppToken(AppWindowToken wtoken) { boolean removed = mAppTokens.remove(wtoken); if (mAppTokens.size() == 0) { Loading services/core/java/com/android/server/wm/WindowContainer.java +39 −6 Original line number Diff line number Diff line Loading @@ -67,17 +67,50 @@ class WindowContainer { mChildren.add(child); } /** Removes this window container and its children */ /** * Removes this window container and its children with no regard for what else might be going on * in the system. For example, the container will be removed during animation if this method is * called which isn't desirable. For most cases you want to call {@link #removeIfPossible()} * which allows the system to defer removal until a suitable time. */ @CallSuper void remove() { void removeImmediately() { while (!mChildren.isEmpty()) { final WindowContainer child = mChildren.removeLast(); child.remove(); final WindowContainer child = mChildren.peekLast(); child.removeImmediately(); // Need to do this after calling remove on the child because the child might try to // remove/detach itself from its parent which will cause an exception if we remove // it before calling remove on the child. mChildren.remove(child); } if (mParent != null) { mParent.mChildren.remove(this); mParent = null; mParent.detachChild(this); } } /** * Removes this window container and its children taking care not to remove them during a * critical stage in the system. For example, some containers will not be removed during * animation if this method is called. */ // TODO: figure-out implementation that works best for this. // E.g. when do we remove from parent list? maybe not... void removeIfPossible() { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); wc.removeIfPossible(); } } /** Detaches the input child container from this container which is its parent. */ @CallSuper void detachChild(WindowContainer child) { if (mChildren.remove(child)) { child.mParent = null; } else { throw new IllegalArgumentException("detachChild: container=" + child + " is not a child of container=" + this); } } Loading services/core/java/com/android/server/wm/WindowManagerService.java +6 −4 Original line number Diff line number Diff line Loading @@ -249,7 +249,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub Loading Loading @@ -1971,7 +1970,10 @@ public class WindowManagerService extends IWindowManager.Stub /** * Performs some centralized bookkeeping clean-up on the window that is being removed. * NOTE: Should only be called from {@link WindowState#remove()} * NOTE: Should only be called from {@link WindowState#removeImmediately()} * TODO: Maybe better handled with a method {@link WindowContainer#detachChild} if we can * figure-out a good way to have all parents of a WindowState doing the same thing without * forgetting to add the wiring when a new parent of WindowState is added. */ void postWindowRemoveCleanupLocked(WindowState win) { if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win); Loading Loading @@ -3831,7 +3833,7 @@ public class WindowManagerService extends IWindowManager.Stub // soon as their animations are complete wtoken.mAppAnimator.clearAnimation(); wtoken.mAppAnimator.animating = false; wtoken.removeAppFromTaskLocked(); wtoken.removeIfPossible(); } wtoken.removed = true; Loading Loading @@ -10533,7 +10535,7 @@ public class WindowManagerService extends IWindowManager.Stub public void removeWindowToken(IBinder token, boolean removeWindows) { synchronized(mWindowMap) { if (removeWindows) { WindowToken wtoken = mTokenMap.remove(token); final WindowToken wtoken = mTokenMap.remove(token); if (wtoken != null) { wtoken.removeAllWindows(); } Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +7 −11 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ class AppWindowToken extends WindowToken { final boolean voiceInteraction; Task mTask; // TODO: Have a fillParent variable in WindowContainer to this? boolean appFullscreen; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean layoutConfigChanges; Loading @@ -100,7 +101,7 @@ class AppWindowToken extends WindowToken { // These are to track the app's real drawing status if there were no saved surfaces. boolean allDrawnExcludingSaved; int numInterestingWindowsExcludingSaved; int numDrawnWindowsExclusingSaved; int numDrawnWindowsExcludingSaved; // Is this window's surface needed? This is almost like hidden, except // it will sometimes be true a little earlier: when the token has Loading Loading @@ -133,6 +134,7 @@ class AppWindowToken extends WindowToken { // Input application handle used by the input dispatcher. final InputApplicationHandle mInputApplicationHandle; // TODO: Have a WindowContainer state for tracking exiting/deferred removal. boolean mIsExiting; boolean mLaunchTaskBehind; Loading Loading @@ -356,18 +358,12 @@ class AppWindowToken extends WindowToken { return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable; } void removeAppFromTaskLocked() { @Override void removeIfPossible() { mIsExiting = false; removeAllWindows(); // Use local variable because removeAppToken will null out mTask. final Task task = mTask; if (task != null) { if (!task.removeAppToken(this)) { Slog.e(TAG, "removeAppFromTaskLocked: token=" + this + " not found."); } task.mStack.mExitingAppTokens.remove(this); if (mTask != null) { mTask.detachChild(this); } } Loading
services/core/java/com/android/server/wm/DisplayContent.java +1 −1 Original line number Diff line number Diff line Loading @@ -515,7 +515,7 @@ class DisplayContent { for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { AppWindowToken wtoken = tokens.get(tokenNdx); if (wtoken.mIsExiting) { wtoken.removeAppFromTaskLocked(); wtoken.removeIfPossible(); } } } Loading
services/core/java/com/android/server/wm/Task.java +8 −0 Original line number Diff line number Diff line Loading @@ -179,6 +179,14 @@ class Task implements DimLayer.DimLayerUser { } } // TODO: Don't forget to switch to WC.detachChild void detachChild(AppWindowToken wtoken) { if (!removeAppToken(wtoken)) { Slog.e(TAG, "detachChild: token=" + this + " not found."); } mStack.mExitingAppTokens.remove(wtoken); } boolean removeAppToken(AppWindowToken wtoken) { boolean removed = mAppTokens.remove(wtoken); if (mAppTokens.size() == 0) { Loading
services/core/java/com/android/server/wm/WindowContainer.java +39 −6 Original line number Diff line number Diff line Loading @@ -67,17 +67,50 @@ class WindowContainer { mChildren.add(child); } /** Removes this window container and its children */ /** * Removes this window container and its children with no regard for what else might be going on * in the system. For example, the container will be removed during animation if this method is * called which isn't desirable. For most cases you want to call {@link #removeIfPossible()} * which allows the system to defer removal until a suitable time. */ @CallSuper void remove() { void removeImmediately() { while (!mChildren.isEmpty()) { final WindowContainer child = mChildren.removeLast(); child.remove(); final WindowContainer child = mChildren.peekLast(); child.removeImmediately(); // Need to do this after calling remove on the child because the child might try to // remove/detach itself from its parent which will cause an exception if we remove // it before calling remove on the child. mChildren.remove(child); } if (mParent != null) { mParent.mChildren.remove(this); mParent = null; mParent.detachChild(this); } } /** * Removes this window container and its children taking care not to remove them during a * critical stage in the system. For example, some containers will not be removed during * animation if this method is called. */ // TODO: figure-out implementation that works best for this. // E.g. when do we remove from parent list? maybe not... void removeIfPossible() { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); wc.removeIfPossible(); } } /** Detaches the input child container from this container which is its parent. */ @CallSuper void detachChild(WindowContainer child) { if (mChildren.remove(child)) { child.mParent = null; } else { throw new IllegalArgumentException("detachChild: container=" + child + " is not a child of container=" + this); } } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +6 −4 Original line number Diff line number Diff line Loading @@ -249,7 +249,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub Loading Loading @@ -1971,7 +1970,10 @@ public class WindowManagerService extends IWindowManager.Stub /** * Performs some centralized bookkeeping clean-up on the window that is being removed. * NOTE: Should only be called from {@link WindowState#remove()} * NOTE: Should only be called from {@link WindowState#removeImmediately()} * TODO: Maybe better handled with a method {@link WindowContainer#detachChild} if we can * figure-out a good way to have all parents of a WindowState doing the same thing without * forgetting to add the wiring when a new parent of WindowState is added. */ void postWindowRemoveCleanupLocked(WindowState win) { if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win); Loading Loading @@ -3831,7 +3833,7 @@ public class WindowManagerService extends IWindowManager.Stub // soon as their animations are complete wtoken.mAppAnimator.clearAnimation(); wtoken.mAppAnimator.animating = false; wtoken.removeAppFromTaskLocked(); wtoken.removeIfPossible(); } wtoken.removed = true; Loading Loading @@ -10533,7 +10535,7 @@ public class WindowManagerService extends IWindowManager.Stub public void removeWindowToken(IBinder token, boolean removeWindows) { synchronized(mWindowMap) { if (removeWindows) { WindowToken wtoken = mTokenMap.remove(token); final WindowToken wtoken = mTokenMap.remove(token); if (wtoken != null) { wtoken.removeAllWindows(); } Loading