Loading services/core/java/com/android/server/wm/AppWindowToken.java +3 −3 Original line number Diff line number Diff line Loading @@ -362,7 +362,7 @@ class AppWindowToken extends WindowToken { win.destroyOrSaveSurface(); if (win.mRemoveOnExit) { win.removeLocked(); win.remove(); } final DisplayContent displayContent = win.getDisplayContent(); if (displayContent != null && !displayList.contains(displayContent)) { Loading Loading @@ -680,10 +680,10 @@ class AppWindowToken extends WindowToken { candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false; } // Since the window already timed out, remove it immediately now. // Use WindowState#removeLocked() instead of removeWindowLocked(), as the latter // Use WindowState#remove() instead of removeWindowLocked(), as the latter // delays removal on certain conditions, which will leave the stale window in the // stack and marked mWillReplaceWindow=false, so the window will never be removed. candidate.removeLocked(); candidate.remove(); } } Loading services/core/java/com/android/server/wm/WindowContainer.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.wm; import android.annotation.CallSuper; import java.util.Comparator; import java.util.LinkedList; /** * Defines common functionality for classes that can hold windows directly or through their * children. * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime * changes are made to this class. */ class WindowContainer { // The parent of this window container. private WindowContainer mParent = null; // List of children for this window container. List is in z-order as the children appear on // screen with the top-most window container at the tail of the list. protected final LinkedList<WindowContainer> mChildren = new LinkedList(); protected WindowContainer getParent() { return mParent; } /** * Adds the input window container has a child of this container in order based on the input * comparator. * @param child The window container to add as a child of this window container. * @param comparator Comparator to use in determining the position the child should be added to. * If null, the child will be added to the top. */ @CallSuper protected void addChild(WindowContainer child, Comparator<WindowContainer> comparator) { child.mParent = this; if (mChildren.isEmpty() || comparator == null) { mChildren.add(child); return; } final int count = mChildren.size(); for (int i = 0; i < count; i++) { if (comparator.compare(child, mChildren.get(i)) < 0) { mChildren.add(i, child); return; } } mChildren.add(child); } /** Removes this window container and its children */ @CallSuper void remove() { while (!mChildren.isEmpty()) { final WindowContainer child = mChildren.removeLast(); child.remove(); } if (mParent != null) { mParent.mChildren.remove(this); mParent = null; } } /** Returns true if this window container has the input child. */ boolean hasChild(WindowContainer child) { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer current = mChildren.get(i); if (current == child || current.hasChild(child)) { return true; } } return false; } } services/core/java/com/android/server/wm/WindowManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -2406,7 +2406,7 @@ public class WindowManagerService extends IWindowManager.Stub } } win.removeLocked(); win.remove(); // Removing a visible window will effect the computed orientation // So just update orientation if needed. if (wasVisible && updateOrientationFromAppTokensLocked(false)) { Loading @@ -2418,7 +2418,7 @@ 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#removeLocked()} * NOTE: Should only be called from {@link WindowState#remove()} */ void postWindowRemoveCleanupLocked(WindowState win) { if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win); Loading services/core/java/com/android/server/wm/WindowState.java +72 −90 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ import com.android.server.input.InputWindowHandle; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedList; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; Loading Loading @@ -113,6 +115,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; 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.WindowManagerService.TYPE_LAYER_MULTIPLIER; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET; import static com.android.server.wm.WindowStateAnimator.COMMIT_DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW; Loading @@ -127,7 +131,7 @@ class WindowList extends ArrayList<WindowState> { /** * A window in the window manager. */ final class WindowState implements WindowManagerPolicy.WindowState { class WindowState extends WindowContainer implements WindowManagerPolicy.WindowState { static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM; // The minimal size of a window within the usable area of the freeform stack. Loading Loading @@ -160,8 +164,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // modified they will need to be locked. final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); final DeathRecipient mDeathRecipient; private final WindowState mParentWindow; private final WindowList mChildWindows = new WindowList(); private boolean mIsChildWindow; final int mBaseLayer; final int mSubLayer; final boolean mLayoutAttached; Loading Loading @@ -511,6 +514,22 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ boolean mSeamlesslyRotated = false; /** * Compares to window sub-layers and returns -1 if the first is lesser than the second in terms * of z-order and 1 otherwise. */ private static final Comparator<WindowContainer> sWindowSubLayerComparator = (w1, w2) -> { final int layer1 = ((WindowState)w1).mSubLayer; final int layer2 = ((WindowState)w2).mSubLayer; if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) { // We insert the child window into the list ordered by the sub-layer. // For same sub-layers, the negative one should go below others; the positive one should // go above others. return -1; } return 1; }; WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent, int ownerId) { Loading Loading @@ -549,7 +568,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { c.asBinder().linkToDeath(deathRecipient, 0); } catch (RemoteException e) { mDeathRecipient = null; mParentWindow = null; mIsChildWindow = false; mLayoutAttached = false; mIsImWindow = false; mIsWallpaper = false; Loading @@ -562,60 +581,35 @@ final class WindowState implements WindowManagerPolicy.WindowState { } mDeathRecipient = deathRecipient; if ((mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW)) { if ((mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW)) { // The multiplier here is to reserve space for multiple // windows in the same type layer. mBaseLayer = mPolicy.windowTypeToLayerLw( parentWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER + WindowManagerService.TYPE_LAYER_OFFSET; mBaseLayer = mPolicy.windowTypeToLayerLw(parentWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); mParentWindow = parentWindow; if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mParentWindow); mIsChildWindow = true; final WindowList childWindows = mParentWindow.mChildWindows; final int numChildWindows = childWindows.size(); if (numChildWindows == 0) { childWindows.add(this); } else { boolean added = false; for (int i = 0; i < numChildWindows; i++) { final int childSubLayer = childWindows.get(i).mSubLayer; if (mSubLayer < childSubLayer || (mSubLayer == childSubLayer && childSubLayer < 0)) { // We insert the child window into the list ordered by the sub-layer. For // same sub-layers, the negative one should go below others; the positive // one should go above others. childWindows.add(i, this); added = true; break; } } if (!added) { childWindows.add(this); } } if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow); parentWindow.addChild(this, sWindowSubLayerComparator); mLayoutAttached = mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; mIsImWindow = parentWindow.mAttrs.type == TYPE_INPUT_METHOD || parentWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = parentWindow.mAttrs.type == TYPE_WALLPAPER; mIsFloatingLayer = mIsImWindow || mIsWallpaper; } else { // The multiplier here is to reserve space for multiple // windows in the same type layer. mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER + WindowManagerService.TYPE_LAYER_OFFSET; * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; mSubLayer = 0; mParentWindow = null; mIsChildWindow = false; mLayoutAttached = false; mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; mIsFloatingLayer = mIsImWindow || mIsWallpaper; } mIsFloatingLayer = mIsImWindow || mIsWallpaper; final WindowState appWin = getTopParentWindow(); WindowToken appToken = appWin.mToken; Loading Loading @@ -1407,7 +1401,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mHasSurface && (mContentChanged || mMovedByResize) && !mAnimatingExit && mService.okToDisplay() && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) && (!isChildWindow() || !mParentWindow.hasMoved()); && (!mIsChildWindow || !getParentWindow().hasMoved()); } boolean isObscuringFullscreen(final DisplayInfo displayInfo) { Loading Loading @@ -1448,19 +1442,16 @@ final class WindowState implements WindowManagerPolicy.WindowState { && mAppToken.mTask.mStack.isAdjustedForMinimizedDock(); } void removeLocked() { @Override void remove() { super.remove(); if (mRemoved) { // Nothing to do. if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "WS.removeLocked: " + this + " Already removed..."); if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "WS.remove: " + this + " Already removed..."); return; } for (int i = mChildWindows.size() - 1; i >= 0; i--) { final WindowState child = mChildWindows.get(i); Slog.w(TAG_WM, "Force-removing child win " + child + " from container " + this); child.removeLocked(); } mRemoved = true; if (mService.mInputMethodTarget == this) { Loading @@ -1476,10 +1467,6 @@ final class WindowState implements WindowManagerPolicy.WindowState { disposeInputChannel(); if (isChildWindow()) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mParentWindow); mParentWindow.mChildWindows.remove(this); } mWinAnimator.destroyDeferredSurfaceLocked(); mWinAnimator.destroySurfaceLocked(); mSession.windowRemovedLocked(); Loading Loading @@ -1652,7 +1639,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { win.mReplacingWindow = null; mSkipEnterAnimationForSeamlessReplacement = false; if (win.mAnimatingExit || !animateReplacingWindow) { win.removeLocked(); win.remove(); } } } Loading Loading @@ -2556,8 +2543,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); pw.print(" h="); pw.println(mLastRequestedHeight); } if (isChildWindow() || mLayoutAttached) { pw.print(prefix); pw.print("mParentWindow="); pw.print(mParentWindow); if (mIsChildWindow || mLayoutAttached) { pw.print(prefix); pw.print("mParentWindow="); pw.print(getParentWindow()); pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); } if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { Loading Loading @@ -2743,7 +2730,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mLastTitle = title; mWasExiting = mAnimatingExit; mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) + " u" + UserHandle.getUserId(mSession.mUid) + " u" + UserHandle.getUserId(mOwnerUid) + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}"); } return mStringNameCache; Loading Loading @@ -2775,7 +2762,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // but SurfaceViews want to be always at a specific location so we don't fit it to the // display. final boolean fitToDisplay = (task == null || !nonFullscreenTask) || (isChildWindow() && !noLimits); || (mIsChildWindow && !noLimits); float x, y; int w,h; Loading Loading @@ -2846,16 +2833,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } boolean isChildWindow() { return mParentWindow != null; } boolean hasChild(WindowState child) { for (int i = mChildWindows.size() - 1; i >= 0; --i) { if (mChildWindows.get(i) == child) { return true; } } return false; return mIsChildWindow; } /** Loading @@ -2864,29 +2842,33 @@ final class WindowState implements WindowManagerPolicy.WindowState { WindowState getBottomChild() { // Child windows are z-ordered based on sub-layer using {@link #sWindowSubLayerComparator} // and the child with the lowest z-order will be at the head of the list. return mChildWindows.isEmpty() ? null : mChildWindows.get(0); return (WindowState) mChildren.peekFirst(); } boolean layoutInParentFrame() { return isChildWindow() && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; return mIsChildWindow && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; } /** Returns the parent window if this is a child of another window, else null. */ WindowState getParentWindow() { return mParentWindow; // NOTE: We are not calling getParent() directly as the WindowState might be a child of a // WindowContainer that isn't a WindowState. return (mIsChildWindow) ? ((WindowState) super.getParent()) : null; } /** Returns the topmost parent window if this is a child of another window, else this. */ WindowState getTopParentWindow() { WindowState w = this; while (w.isChildWindow()) { while (w.mIsChildWindow) { w = w.getParentWindow(); } return w; } boolean isParentWindowHidden() { return (mParentWindow != null) ? mParentWindow.mHidden : false; final WindowState parent = getParentWindow(); return (parent == null) ? false : parent.mHidden; } void setReplacing(boolean animate) { Loading Loading @@ -2950,7 +2932,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // them at such phases, as they won't be covered by window preservation, // and in general we expect them to return following relaunch. boolean shouldBeReplacedWithChildren() { return isChildWindow() || mAttrs.type == TYPE_APPLICATION; return mIsChildWindow || mAttrs.type == TYPE_APPLICATION; } public int getRotationAnimationHint() { Loading Loading @@ -2991,8 +2973,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { mHidden = false; final DisplayContent displayContent = getDisplayContent(); for (int i = mChildWindows.size(); i >= 0; --i) { final WindowState c = mChildWindows.get(i); for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowState c = (WindowState) mChildren.get(i); if (c.mWinAnimator.mSurfaceController != null) { c.performShowLocked(); // It hadn't been shown, which means layout not performed on it, so now we Loading Loading @@ -3044,30 +3026,29 @@ final class WindowState implements WindowManagerPolicy.WindowState { windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor; windowInfo.focused = isFocused(); if (isChildWindow()) { windowInfo.parentToken = mParentWindow.mClient.asBinder(); if (mIsChildWindow) { windowInfo.parentToken = getParentWindow().mClient.asBinder(); } final int childCount = mChildWindows.size(); final int childCount = mChildren.size(); if (childCount > 0) { if (windowInfo.childTokens == null) { windowInfo.childTokens = new ArrayList<>(); windowInfo.childTokens = new ArrayList(childCount); } for (int j = 0; j < childCount; j++) { final WindowState child = mChildWindows.get(j); final WindowState child = (WindowState) mChildren.get(j); windowInfo.childTokens.add(child.mClient.asBinder()); } } return windowInfo; } void adjustAnimLayer(int adj) { mWinAnimator.mAnimLayer = mLayer + adj; if (DEBUG_LAYERS) Slog.v(TAG_WM, "win=" + this + " anim layer: " + mWinAnimator.mAnimLayer); for (int i = mChildWindows.size() - 1; i >= 0; i--) { final WindowState child = mChildWindows.get(i); child.adjustAnimLayer(adj); for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowState childWindow = (WindowState) mChildren.get(i); childWindow.adjustAnimLayer(adj); } } Loading @@ -3078,10 +3059,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { final WindowList windows = getWindowList(); // Adding child windows relies on child windows being ordered by mSubLayer using // {@link #sWindowSubLayerComparator}. final int childCount = mChildWindows.size(); final int childCount = mChildren.size(); boolean winAdded = false; for (int j = 0; j < childCount; j++) { WindowState child = mChildWindows.get(j); final WindowState child = (WindowState) mChildren.get(j); if (!winAdded && child.mSubLayer >= 0) { if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding child window at " + index + ": " + child); Loading Loading @@ -3116,10 +3097,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this); windows.remove(wpos); mService.mWindowsChanged = true; int childCount = mChildWindows.size(); int childCount = mChildren.size(); while (childCount > 0) { childCount--; final WindowState cw = mChildWindows.get(childCount); final WindowState cw = (WindowState) mChildren.get(childCount); int cpos = windows.indexOf(cw); if (cpos >= 0) { if (cpos < interestingPos) interestingPos--; Loading @@ -3136,11 +3117,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { + ": exiting=" + mAnimatingExit + " remove=" + mRemoveOnExit + " windowAnimating=" + mWinAnimator.isWindowAnimationSet()); if (!mChildWindows.isEmpty()) { if (!mChildren.isEmpty()) { // Copying to a different list as multiple children can be removed. final WindowList childWindows = new WindowList(mChildWindows); // TODO: Not sure if we really need to copy this into a different list. final LinkedList childWindows = new LinkedList(mChildren); for (int i = childWindows.size() - 1; i >= 0; i--) { childWindows.get(i).onExitAnimationDone(); ((WindowState)childWindows.get(i)).onExitAnimationDone(); } } Loading services/core/java/com/android/server/wm/WindowSurfacePlacer.java +2 −2 Original line number Diff line number Diff line Loading @@ -215,7 +215,7 @@ class WindowSurfacePlacer { while (!mService.mForceRemoves.isEmpty()) { final WindowState ws = mService.mForceRemoves.remove(0); Slog.i(TAG, "Force removing: " + ws); ws.removeLocked(); ws.remove(); } Slog.w(TAG, "Due to memory failure, waiting a bit for next layout"); Object tmp = new Object(); Loading Loading @@ -545,7 +545,7 @@ class WindowSurfacePlacer { DisplayContentList displayList = new DisplayContentList(); for (i = 0; i < N; i++) { final WindowState w = mService.mPendingRemoveTmp[i]; w.removeLocked(); w.remove(); final DisplayContent displayContent = w.getDisplayContent(); if (displayContent != null && !displayList.contains(displayContent)) { displayList.add(displayContent); Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +3 −3 Original line number Diff line number Diff line Loading @@ -362,7 +362,7 @@ class AppWindowToken extends WindowToken { win.destroyOrSaveSurface(); if (win.mRemoveOnExit) { win.removeLocked(); win.remove(); } final DisplayContent displayContent = win.getDisplayContent(); if (displayContent != null && !displayList.contains(displayContent)) { Loading Loading @@ -680,10 +680,10 @@ class AppWindowToken extends WindowToken { candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false; } // Since the window already timed out, remove it immediately now. // Use WindowState#removeLocked() instead of removeWindowLocked(), as the latter // Use WindowState#remove() instead of removeWindowLocked(), as the latter // delays removal on certain conditions, which will leave the stale window in the // stack and marked mWillReplaceWindow=false, so the window will never be removed. candidate.removeLocked(); candidate.remove(); } } Loading
services/core/java/com/android/server/wm/WindowContainer.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.server.wm; import android.annotation.CallSuper; import java.util.Comparator; import java.util.LinkedList; /** * Defines common functionality for classes that can hold windows directly or through their * children. * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime * changes are made to this class. */ class WindowContainer { // The parent of this window container. private WindowContainer mParent = null; // List of children for this window container. List is in z-order as the children appear on // screen with the top-most window container at the tail of the list. protected final LinkedList<WindowContainer> mChildren = new LinkedList(); protected WindowContainer getParent() { return mParent; } /** * Adds the input window container has a child of this container in order based on the input * comparator. * @param child The window container to add as a child of this window container. * @param comparator Comparator to use in determining the position the child should be added to. * If null, the child will be added to the top. */ @CallSuper protected void addChild(WindowContainer child, Comparator<WindowContainer> comparator) { child.mParent = this; if (mChildren.isEmpty() || comparator == null) { mChildren.add(child); return; } final int count = mChildren.size(); for (int i = 0; i < count; i++) { if (comparator.compare(child, mChildren.get(i)) < 0) { mChildren.add(i, child); return; } } mChildren.add(child); } /** Removes this window container and its children */ @CallSuper void remove() { while (!mChildren.isEmpty()) { final WindowContainer child = mChildren.removeLast(); child.remove(); } if (mParent != null) { mParent.mChildren.remove(this); mParent = null; } } /** Returns true if this window container has the input child. */ boolean hasChild(WindowContainer child) { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer current = mChildren.get(i); if (current == child || current.hasChild(child)) { return true; } } return false; } }
services/core/java/com/android/server/wm/WindowManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -2406,7 +2406,7 @@ public class WindowManagerService extends IWindowManager.Stub } } win.removeLocked(); win.remove(); // Removing a visible window will effect the computed orientation // So just update orientation if needed. if (wasVisible && updateOrientationFromAppTokensLocked(false)) { Loading @@ -2418,7 +2418,7 @@ 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#removeLocked()} * NOTE: Should only be called from {@link WindowState#remove()} */ void postWindowRemoveCleanupLocked(WindowState win) { if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win); Loading
services/core/java/com/android/server/wm/WindowState.java +72 −90 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ import com.android.server.input.InputWindowHandle; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedList; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; Loading Loading @@ -113,6 +115,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; 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.WindowManagerService.TYPE_LAYER_MULTIPLIER; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET; import static com.android.server.wm.WindowStateAnimator.COMMIT_DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW; Loading @@ -127,7 +131,7 @@ class WindowList extends ArrayList<WindowState> { /** * A window in the window manager. */ final class WindowState implements WindowManagerPolicy.WindowState { class WindowState extends WindowContainer implements WindowManagerPolicy.WindowState { static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM; // The minimal size of a window within the usable area of the freeform stack. Loading Loading @@ -160,8 +164,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // modified they will need to be locked. final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); final DeathRecipient mDeathRecipient; private final WindowState mParentWindow; private final WindowList mChildWindows = new WindowList(); private boolean mIsChildWindow; final int mBaseLayer; final int mSubLayer; final boolean mLayoutAttached; Loading Loading @@ -511,6 +514,22 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ boolean mSeamlesslyRotated = false; /** * Compares to window sub-layers and returns -1 if the first is lesser than the second in terms * of z-order and 1 otherwise. */ private static final Comparator<WindowContainer> sWindowSubLayerComparator = (w1, w2) -> { final int layer1 = ((WindowState)w1).mSubLayer; final int layer2 = ((WindowState)w2).mSubLayer; if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) { // We insert the child window into the list ordered by the sub-layer. // For same sub-layers, the negative one should go below others; the positive one should // go above others. return -1; } return 1; }; WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent, int ownerId) { Loading Loading @@ -549,7 +568,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { c.asBinder().linkToDeath(deathRecipient, 0); } catch (RemoteException e) { mDeathRecipient = null; mParentWindow = null; mIsChildWindow = false; mLayoutAttached = false; mIsImWindow = false; mIsWallpaper = false; Loading @@ -562,60 +581,35 @@ final class WindowState implements WindowManagerPolicy.WindowState { } mDeathRecipient = deathRecipient; if ((mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW)) { if ((mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW)) { // The multiplier here is to reserve space for multiple // windows in the same type layer. mBaseLayer = mPolicy.windowTypeToLayerLw( parentWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER + WindowManagerService.TYPE_LAYER_OFFSET; mBaseLayer = mPolicy.windowTypeToLayerLw(parentWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); mParentWindow = parentWindow; if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mParentWindow); mIsChildWindow = true; final WindowList childWindows = mParentWindow.mChildWindows; final int numChildWindows = childWindows.size(); if (numChildWindows == 0) { childWindows.add(this); } else { boolean added = false; for (int i = 0; i < numChildWindows; i++) { final int childSubLayer = childWindows.get(i).mSubLayer; if (mSubLayer < childSubLayer || (mSubLayer == childSubLayer && childSubLayer < 0)) { // We insert the child window into the list ordered by the sub-layer. For // same sub-layers, the negative one should go below others; the positive // one should go above others. childWindows.add(i, this); added = true; break; } } if (!added) { childWindows.add(this); } } if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow); parentWindow.addChild(this, sWindowSubLayerComparator); mLayoutAttached = mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; mIsImWindow = parentWindow.mAttrs.type == TYPE_INPUT_METHOD || parentWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = parentWindow.mAttrs.type == TYPE_WALLPAPER; mIsFloatingLayer = mIsImWindow || mIsWallpaper; } else { // The multiplier here is to reserve space for multiple // windows in the same type layer. mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER + WindowManagerService.TYPE_LAYER_OFFSET; * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; mSubLayer = 0; mParentWindow = null; mIsChildWindow = false; mLayoutAttached = false; mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; mIsFloatingLayer = mIsImWindow || mIsWallpaper; } mIsFloatingLayer = mIsImWindow || mIsWallpaper; final WindowState appWin = getTopParentWindow(); WindowToken appToken = appWin.mToken; Loading Loading @@ -1407,7 +1401,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mHasSurface && (mContentChanged || mMovedByResize) && !mAnimatingExit && mService.okToDisplay() && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) && (!isChildWindow() || !mParentWindow.hasMoved()); && (!mIsChildWindow || !getParentWindow().hasMoved()); } boolean isObscuringFullscreen(final DisplayInfo displayInfo) { Loading Loading @@ -1448,19 +1442,16 @@ final class WindowState implements WindowManagerPolicy.WindowState { && mAppToken.mTask.mStack.isAdjustedForMinimizedDock(); } void removeLocked() { @Override void remove() { super.remove(); if (mRemoved) { // Nothing to do. if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "WS.removeLocked: " + this + " Already removed..."); if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "WS.remove: " + this + " Already removed..."); return; } for (int i = mChildWindows.size() - 1; i >= 0; i--) { final WindowState child = mChildWindows.get(i); Slog.w(TAG_WM, "Force-removing child win " + child + " from container " + this); child.removeLocked(); } mRemoved = true; if (mService.mInputMethodTarget == this) { Loading @@ -1476,10 +1467,6 @@ final class WindowState implements WindowManagerPolicy.WindowState { disposeInputChannel(); if (isChildWindow()) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mParentWindow); mParentWindow.mChildWindows.remove(this); } mWinAnimator.destroyDeferredSurfaceLocked(); mWinAnimator.destroySurfaceLocked(); mSession.windowRemovedLocked(); Loading Loading @@ -1652,7 +1639,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { win.mReplacingWindow = null; mSkipEnterAnimationForSeamlessReplacement = false; if (win.mAnimatingExit || !animateReplacingWindow) { win.removeLocked(); win.remove(); } } } Loading Loading @@ -2556,8 +2543,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); pw.print(" h="); pw.println(mLastRequestedHeight); } if (isChildWindow() || mLayoutAttached) { pw.print(prefix); pw.print("mParentWindow="); pw.print(mParentWindow); if (mIsChildWindow || mLayoutAttached) { pw.print(prefix); pw.print("mParentWindow="); pw.print(getParentWindow()); pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); } if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { Loading Loading @@ -2743,7 +2730,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mLastTitle = title; mWasExiting = mAnimatingExit; mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) + " u" + UserHandle.getUserId(mSession.mUid) + " u" + UserHandle.getUserId(mOwnerUid) + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}"); } return mStringNameCache; Loading Loading @@ -2775,7 +2762,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // but SurfaceViews want to be always at a specific location so we don't fit it to the // display. final boolean fitToDisplay = (task == null || !nonFullscreenTask) || (isChildWindow() && !noLimits); || (mIsChildWindow && !noLimits); float x, y; int w,h; Loading Loading @@ -2846,16 +2833,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } boolean isChildWindow() { return mParentWindow != null; } boolean hasChild(WindowState child) { for (int i = mChildWindows.size() - 1; i >= 0; --i) { if (mChildWindows.get(i) == child) { return true; } } return false; return mIsChildWindow; } /** Loading @@ -2864,29 +2842,33 @@ final class WindowState implements WindowManagerPolicy.WindowState { WindowState getBottomChild() { // Child windows are z-ordered based on sub-layer using {@link #sWindowSubLayerComparator} // and the child with the lowest z-order will be at the head of the list. return mChildWindows.isEmpty() ? null : mChildWindows.get(0); return (WindowState) mChildren.peekFirst(); } boolean layoutInParentFrame() { return isChildWindow() && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; return mIsChildWindow && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; } /** Returns the parent window if this is a child of another window, else null. */ WindowState getParentWindow() { return mParentWindow; // NOTE: We are not calling getParent() directly as the WindowState might be a child of a // WindowContainer that isn't a WindowState. return (mIsChildWindow) ? ((WindowState) super.getParent()) : null; } /** Returns the topmost parent window if this is a child of another window, else this. */ WindowState getTopParentWindow() { WindowState w = this; while (w.isChildWindow()) { while (w.mIsChildWindow) { w = w.getParentWindow(); } return w; } boolean isParentWindowHidden() { return (mParentWindow != null) ? mParentWindow.mHidden : false; final WindowState parent = getParentWindow(); return (parent == null) ? false : parent.mHidden; } void setReplacing(boolean animate) { Loading Loading @@ -2950,7 +2932,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // them at such phases, as they won't be covered by window preservation, // and in general we expect them to return following relaunch. boolean shouldBeReplacedWithChildren() { return isChildWindow() || mAttrs.type == TYPE_APPLICATION; return mIsChildWindow || mAttrs.type == TYPE_APPLICATION; } public int getRotationAnimationHint() { Loading Loading @@ -2991,8 +2973,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { mHidden = false; final DisplayContent displayContent = getDisplayContent(); for (int i = mChildWindows.size(); i >= 0; --i) { final WindowState c = mChildWindows.get(i); for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowState c = (WindowState) mChildren.get(i); if (c.mWinAnimator.mSurfaceController != null) { c.performShowLocked(); // It hadn't been shown, which means layout not performed on it, so now we Loading Loading @@ -3044,30 +3026,29 @@ final class WindowState implements WindowManagerPolicy.WindowState { windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor; windowInfo.focused = isFocused(); if (isChildWindow()) { windowInfo.parentToken = mParentWindow.mClient.asBinder(); if (mIsChildWindow) { windowInfo.parentToken = getParentWindow().mClient.asBinder(); } final int childCount = mChildWindows.size(); final int childCount = mChildren.size(); if (childCount > 0) { if (windowInfo.childTokens == null) { windowInfo.childTokens = new ArrayList<>(); windowInfo.childTokens = new ArrayList(childCount); } for (int j = 0; j < childCount; j++) { final WindowState child = mChildWindows.get(j); final WindowState child = (WindowState) mChildren.get(j); windowInfo.childTokens.add(child.mClient.asBinder()); } } return windowInfo; } void adjustAnimLayer(int adj) { mWinAnimator.mAnimLayer = mLayer + adj; if (DEBUG_LAYERS) Slog.v(TAG_WM, "win=" + this + " anim layer: " + mWinAnimator.mAnimLayer); for (int i = mChildWindows.size() - 1; i >= 0; i--) { final WindowState child = mChildWindows.get(i); child.adjustAnimLayer(adj); for (int i = mChildren.size() - 1; i >= 0; i--) { final WindowState childWindow = (WindowState) mChildren.get(i); childWindow.adjustAnimLayer(adj); } } Loading @@ -3078,10 +3059,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { final WindowList windows = getWindowList(); // Adding child windows relies on child windows being ordered by mSubLayer using // {@link #sWindowSubLayerComparator}. final int childCount = mChildWindows.size(); final int childCount = mChildren.size(); boolean winAdded = false; for (int j = 0; j < childCount; j++) { WindowState child = mChildWindows.get(j); final WindowState child = (WindowState) mChildren.get(j); if (!winAdded && child.mSubLayer >= 0) { if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding child window at " + index + ": " + child); Loading Loading @@ -3116,10 +3097,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this); windows.remove(wpos); mService.mWindowsChanged = true; int childCount = mChildWindows.size(); int childCount = mChildren.size(); while (childCount > 0) { childCount--; final WindowState cw = mChildWindows.get(childCount); final WindowState cw = (WindowState) mChildren.get(childCount); int cpos = windows.indexOf(cw); if (cpos >= 0) { if (cpos < interestingPos) interestingPos--; Loading @@ -3136,11 +3117,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { + ": exiting=" + mAnimatingExit + " remove=" + mRemoveOnExit + " windowAnimating=" + mWinAnimator.isWindowAnimationSet()); if (!mChildWindows.isEmpty()) { if (!mChildren.isEmpty()) { // Copying to a different list as multiple children can be removed. final WindowList childWindows = new WindowList(mChildWindows); // TODO: Not sure if we really need to copy this into a different list. final LinkedList childWindows = new LinkedList(mChildren); for (int i = childWindows.size() - 1; i >= 0; i--) { childWindows.get(i).onExitAnimationDone(); ((WindowState)childWindows.get(i)).onExitAnimationDone(); } } Loading
services/core/java/com/android/server/wm/WindowSurfacePlacer.java +2 −2 Original line number Diff line number Diff line Loading @@ -215,7 +215,7 @@ class WindowSurfacePlacer { while (!mService.mForceRemoves.isEmpty()) { final WindowState ws = mService.mForceRemoves.remove(0); Slog.i(TAG, "Force removing: " + ws); ws.removeLocked(); ws.remove(); } Slog.w(TAG, "Due to memory failure, waiting a bit for next layout"); Object tmp = new Object(); Loading Loading @@ -545,7 +545,7 @@ class WindowSurfacePlacer { DisplayContentList displayList = new DisplayContentList(); for (i = 0; i < N; i++) { final WindowState w = mService.mPendingRemoveTmp[i]; w.removeLocked(); w.remove(); final DisplayContent displayContent = w.getDisplayContent(); if (displayContent != null && !displayList.contains(displayContent)) { displayList.add(displayContent); Loading