diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 47f435f0c7cad..7004e355179a1 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1260,7 +1260,6 @@ class AppWindowToken extends WindowToken { fromToken.startingWindow = null; fromToken.startingMoved = true; tStartingWindow.mToken = this; - tStartingWindow.mRootToken = this; tStartingWindow.mAppToken = this; if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index feb5c68e48fc1..10104004bc3bd 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -361,7 +361,7 @@ public class WindowAnimator { + " destroying=" + win.mDestroying + " parentHidden=" + win.isParentWindowHidden() + " vis=" + win.mViewVisibility - + " hidden=" + win.mRootToken.hidden + + " hidden=" + win.mToken.hidden + " anim=" + win.mWinAnimator.mAnimation); } else if (canBeForceHidden) { if (shouldBeForceHidden) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 6648b1cd2dacf..b80af2c808f35 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1461,7 +1461,7 @@ public class WindowManagerService extends IWindowManager.Stub } boolean reportNewConfig = false; - WindowState attachedWindow = null; + WindowState parentWindow = null; long origId; final int type = attrs.type; @@ -1488,14 +1488,14 @@ public class WindowManagerService extends IWindowManager.Stub } if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) { - attachedWindow = windowForClientLocked(null, attrs.token, false); - if (attachedWindow == null) { + parentWindow = windowForClientLocked(null, attrs.token, false); + if (parentWindow == null) { Slog.w(TAG_WM, "Attempted to add window with token that is not a window: " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; } - if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW - && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) { + if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW + && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) { Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; @@ -1507,46 +1507,52 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } - WindowToken token = mTokenMap.get(attrs.token); AppWindowToken atoken = null; + final boolean hasParent = parentWindow != null; + // Use existing parent window token for child windows since they go in the same token + // as there parent window so we can apply the same policy on them. + WindowToken token = mTokenMap.get(hasParent ? parentWindow.mAttrs.token : attrs.token); + // If this is a child window, we want to apply the same type checking rules as the + // parent window type. + final int rootType = hasParent ? parentWindow.mAttrs.type : type; if (token == null) { - if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { + if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { Slog.w(TAG_WM, "Attempted to add application window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (type == TYPE_INPUT_METHOD) { + if (rootType == TYPE_INPUT_METHOD) { Slog.w(TAG_WM, "Attempted to add input method window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (type == TYPE_VOICE_INTERACTION) { + if (rootType == TYPE_VOICE_INTERACTION) { Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (type == TYPE_WALLPAPER) { + if (rootType == TYPE_WALLPAPER) { Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (type == TYPE_DREAM) { + if (rootType == TYPE_DREAM) { Slog.w(TAG_WM, "Attempted to add Dream window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (type == TYPE_QS_DIALOG) { + if (rootType == TYPE_QS_DIALOG) { Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - if (type == TYPE_ACCESSIBILITY_OVERLAY) { + if (rootType == TYPE_ACCESSIBILITY_OVERLAY) { Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } token = new WindowToken(this, attrs.token, -1, false); - } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { + } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) { atoken = token.asAppWindowToken(); if (atoken == null) { Slog.w(TAG_WM, "Attempted to add window with non-application token " @@ -1557,57 +1563,57 @@ public class WindowManagerService extends IWindowManager.Stub + token + ". Aborting."); return WindowManagerGlobal.ADD_APP_EXITING; } - if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) { + if (rootType == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) { // No need for this guy! if (DEBUG_STARTING_WINDOW || localLOGV) Slog.v( TAG_WM, "**** NO NEED TO START: " + attrs.getTitle()); return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED; } - } else if (type == TYPE_INPUT_METHOD) { + } else if (rootType == TYPE_INPUT_METHOD) { if (token.windowType != TYPE_INPUT_METHOD) { Slog.w(TAG_WM, "Attempted to add input method window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (type == TYPE_VOICE_INTERACTION) { + } else if (rootType == TYPE_VOICE_INTERACTION) { if (token.windowType != TYPE_VOICE_INTERACTION) { Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (type == TYPE_WALLPAPER) { + } else if (rootType == TYPE_WALLPAPER) { if (token.windowType != TYPE_WALLPAPER) { Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (type == TYPE_DREAM) { + } else if (rootType == TYPE_DREAM) { if (token.windowType != TYPE_DREAM) { Slog.w(TAG_WM, "Attempted to add Dream window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (type == TYPE_ACCESSIBILITY_OVERLAY) { + } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) { if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) { Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } - } else if (type == TYPE_QS_DIALOG) { + } else if (rootType == TYPE_QS_DIALOG) { if (token.windowType != TYPE_QS_DIALOG) { Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token " + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } } else if (token.asAppWindowToken() != null) { - Slog.w(TAG_WM, "Non-null appWindowToken for system window of type=" + type); + Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType); // It is not valid to use an app token with other system types; we will // instead make a new token for it (as if null had been passed in for the token). attrs.token = null; token = new WindowToken(this, null, -1, false); } - WindowState win = new WindowState(this, session, client, token, attachedWindow, + WindowState win = new WindowState(this, session, client, token, parentWindow, appOp[0], seq, attrs, viewVisibility, displayContent, session.mUid); if (win.mDeathRecipient == null) { // Client has apparently died, so there is no reason to @@ -8190,16 +8196,13 @@ public class WindowManagerService extends IWindowManager.Stub // Internals // ------------------------------------------------------------- - final WindowState windowForClientLocked(Session session, IWindow client, - boolean throwOnError) { + final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) { return windowForClientLocked(session, client.asBinder(), throwOnError); } - final WindowState windowForClientLocked(Session session, IBinder client, - boolean throwOnError) { + final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) { WindowState win = mWindowMap.get(client); - if (localLOGV) Slog.v( - TAG_WM, "Looking up client " + client + ": " + win); + if (localLOGV) Slog.v(TAG_WM, "Looking up client " + client + ": " + win); if (win == null) { RuntimeException ex = new IllegalArgumentException( "Requested window " + client + " does not exist"); @@ -8259,15 +8262,13 @@ public class WindowManagerService extends IWindowManager.Stub i++; } - // Keep whatever windows were below the app windows still below, - // by skipping them. + // Keep whatever windows were below the app windows still below, by skipping them. lastBelow++; i = lastBelow; - // First add all of the exiting app tokens... these are no longer - // in the main app list, but still have windows shown. We put them - // in the back because now that the animation is over we no longer - // will care about them. + // First add all of the exiting app tokens... these are no longer in the main app list, + // but still have windows shown. We put them in the back because now that the animation is + // over we no longer will care about them. final ArrayList stacks = displayContent.getStacks(); final int numStacks = stacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d9836a840e8f4..67a7a09b7efe6 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -165,7 +165,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS final int mOwnerUid; final IWindowId mWindowId; WindowToken mToken; - WindowToken mRootToken; + // The same object as mToken if this is an app window and null for non-app windows. AppWindowToken mAppToken; // mAttrs.flags is tested in animation without being locked. If the bits tested are ever @@ -554,6 +554,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS mClient = c; mAppOp = appOp; mToken = token; + mAppToken = mToken.asAppWindowToken(); mOwnerUid = ownerId; mWindowId = new IWindowId.Stub() { @Override @@ -627,8 +628,6 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS } mIsFloatingLayer = mIsImWindow || mIsWallpaper; - mRootToken = getTopParentWindow().mToken; - mAppToken = mRootToken.asAppWindowToken(); if (mAppToken != null) { final DisplayContent appDisplay = getDisplayContent(); mNotOnAppsDisplay = displayContent != appDisplay; @@ -1192,14 +1191,14 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS */ @Override public boolean isVisibleOrBehindKeyguardLw() { - if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { + if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { return false; } final AppWindowToken atoken = mAppToken; final boolean animating = atoken != null && atoken.mAppAnimator.animation != null; return mHasSurface && !mDestroying && !mAnimatingExit && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) - && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mRootToken.hidden) + && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden) || mWinAnimator.mAnimation != null || animating); } @@ -1217,7 +1216,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS * not the pending requested hidden state. */ boolean isVisibleNow() { - return (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING) + return (!mToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING) && isVisibleUnchecked(); } @@ -1299,11 +1298,11 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS * of a transition that has not yet been started. */ boolean isReadyForDisplay() { - if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { + if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { return false; } return mHasSurface && mPolicyVisibility && !mDestroying - && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mRootToken.hidden) + && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden) || mWinAnimator.mAnimation != null || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null))); } @@ -1313,7 +1312,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS * to the keyguard. */ boolean isReadyForDisplayIgnoringKeyguard() { - if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { + if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { return false; } final AppWindowToken atoken = mAppToken; @@ -1323,7 +1322,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS return false; } return mHasSurface && !mDestroying - && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mRootToken.hidden) + && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden) || mWinAnimator.mAnimation != null || ((atoken != null) && (atoken.mAppAnimator.animation != null) && !mWinAnimator.isDummyAnimation())); @@ -1357,7 +1356,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS final AppWindowToken atoken = mAppToken; return mViewVisibility == View.GONE || !mRelayoutCalled - || (atoken == null && mRootToken.hidden) + || (atoken == null && mToken.hidden) || (atoken != null && atoken.hiddenRequested) || isParentWindowHidden() || (mAnimatingExit && !isAnimatingLw()) @@ -2728,7 +2727,6 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS } if (dumpAll) { pw.print(prefix); pw.print("mToken="); pw.println(mToken); - pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); if (mAppToken != null) { pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken); pw.print(prefix); pw.print(" isAnimatingWithSavedSurface()="); @@ -3020,7 +3018,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS /** Returns the topmost parent window if this is a child of another window, else this. */ WindowState getTopParentWindow() { WindowState w = this; - while (w.mIsChildWindow) { + while (w != null && w.mIsChildWindow) { w = w.getParentWindow(); } return w; diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 25709c5160d1a..c26c07804e53c 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -956,13 +956,13 @@ class WindowSurfacePlacer { if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" - + win.mRootToken.hidden + " hiddenRequested=" + + win.mToken.hidden + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + " parentHidden=" + win.isParentWindowHidden()); else Slog.v(TAG, " VIS: mViewVisibility=" + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" - + win.mRootToken.hidden + " hiddenRequested=" + + win.mToken.hidden + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) + " parentHidden=" + win.isParentWindowHidden()); } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 9f019acc31d8b..f56a0f1efc73e 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -451,6 +451,16 @@ class WindowToken { final int count = windows.size(); for (int i = 0; i < count; i++) { final WindowState win = windows.get(i); + if (win.isChildWindow()) { + // The WindowState.reAddWindowLocked below already takes care of re-adding the + // child windows for any parent window in this token. This is a side effect of + // ensuring child windows are in the same WindowToken as their parent window. + // + // TODO: Can be removed once WindowToken no longer contains child windows. i.e it is + // using WindowContainer which uses the hierarchy to access child windows through + // their parent window. + continue; + } final DisplayContent winDisplayContent = win.getDisplayContent(); if (winDisplayContent == displayContent || winDisplayContent == null) { win.mDisplayContent = displayContent;