diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index fd023476c9e4a..9a25dcc547cfd 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4976,13 +4976,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf, DisplayFrames displayFrames) { - if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { - // Here's a special case: if this attached window is a panel that is above the dock - // window, and the window it is attached to is below the dock window, then the frames we - // computed for the window it is attached to can not be used because the dock is - // effectively part of the underlying window and the attached window is floating on top - // of the whole thing. So, we ignore the attached window and explicitly compute the - // frames that would be appropriate without the dock. + if (!win.isInputMethodTarget() && attached.isInputMethodTarget()) { + // Here's a special case: if the child window is not the 'dock window' + // or input method target, and the window it is attached to is below + // the dock window, then the frames we computed for the window it is + // attached to can not be used because the dock is effectively part + // of the underlying window and the attached window is floating on top + // of the whole thing. So, we ignore the attached window and explicitly + // compute the frames that would be appropriate without the dock. vf.set(displayFrames.mDock); cf.set(displayFrames.mDock); of.set(displayFrames.mDock); @@ -5009,7 +5010,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { cf.set(attached.getContentFrameLw()); if (attached.isVoiceInteraction()) { cf.intersectUnchecked(displayFrames.mVoiceContent); - } else if (attached.getSurfaceLayer() < mDockLayer) { + } else if (win.isInputMethodTarget() || attached.isInputMethodTarget()) { cf.intersectUnchecked(displayFrames.mContent); } } @@ -5500,7 +5501,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf, displayFrames.mDisplayCutout, parentFrameWasClippedByDisplayCutout); - // Dock windows carve out the bottom of the screen, so normal windows // can't appear underneath them. if (type == TYPE_INPUT_METHOD && win.isVisibleLw() diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 0a6ae4e2f2d97..ccbf502bc2b51 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -474,6 +474,8 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { public boolean isInputMethodWindow(); + public boolean isInputMethodTarget(); + public int getDisplayId(); /** diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 30bbfe0b83c4d..54c2e9badc7b0 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -897,7 +897,7 @@ class WindowState extends WindowContainer implements WindowManagerP } final WindowState imeWin = mService.mInputMethodWindow; // IME is up and obscuring this window. Adjust the window position so it is visible. - if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) { + if (imeWin != null && imeWin.isVisibleNow() && isInputMethodTarget()) { if (inFreeformWindowingMode() && mContainingFrame.bottom > contentFrame.bottom) { // In freeform we want to move the top up directly. @@ -1691,13 +1691,6 @@ class WindowState extends WindowContainer implements WindowManagerP return changed; } - // Next up we will notify the client that it's visibility has changed. - // We need to prevent it from destroying child surfaces until - // the animation has finished. - if (!visible && isVisibleNow()) { - mWinAnimator.detachChildren(); - } - if (visible != isVisibleNow()) { if (!runningAppAnimation) { final AccessibilityController accessibilityController = @@ -1885,7 +1878,7 @@ class WindowState extends WindowContainer implements WindowManagerP } final DisplayContent dc = getDisplayContent(); - if (mService.mInputMethodTarget == this) { + if (isInputMethodTarget()) { dc.computeImeTarget(true /* updateImeTarget */); } @@ -3949,7 +3942,7 @@ class WindowState extends WindowContainer implements WindowManagerP private boolean applyInOrderWithImeWindows(ToBooleanFunction callback, boolean traverseTopToBottom) { if (traverseTopToBottom) { - if (mService.mInputMethodTarget == this) { + if (isInputMethodTarget()) { // This window is the current IME target, so we need to process the IME windows // directly above it. if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) { @@ -3963,7 +3956,7 @@ class WindowState extends WindowContainer implements WindowManagerP if (callback.apply(this)) { return true; } - if (mService.mInputMethodTarget == this) { + if (isInputMethodTarget()) { // This window is the current IME target, so we need to process the IME windows // directly above it. if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) { @@ -4673,7 +4666,7 @@ class WindowState extends WindowContainer implements WindowManagerP void assignLayer(Transaction t, int layer) { // See comment in assignRelativeLayerForImeTargetChild if (!isChildWindow() - || (mService.mInputMethodTarget != getParentWindow()) + || (!getParentWindow().isInputMethodTarget()) || !inSplitScreenWindowingMode()) { super.assignLayer(t, layer); return; @@ -4741,6 +4734,11 @@ class WindowState extends WindowContainer implements WindowManagerP mTapExcludeRegionHolder.amendRegion(region, getBounds()); } + @Override + public boolean isInputMethodTarget() { + return mService.mInputMethodTarget == this; + } + private final class MoveAnimationSpec implements AnimationSpec { private final long mDuration; diff --git a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java index 56ba047338a79..7487d4490d9a5 100644 --- a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java +++ b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java @@ -258,4 +258,9 @@ public class FakeWindowState implements WindowManagerPolicy.WindowState { public void writeIdentifierToProto(ProtoOutputStream proto, long fieldId){ throw new UnsupportedOperationException("not implemented"); } + + @Override + public boolean isInputMethodTarget() { + return false; + } }