diff --git a/core/java/android/view/inputmethod/InputMethodManagerInternal.java b/core/java/android/view/inputmethod/InputMethodManagerInternal.java index ce9908cce0937..77df4e3883a7f 100644 --- a/core/java/android/view/inputmethod/InputMethodManagerInternal.java +++ b/core/java/android/view/inputmethod/InputMethodManagerInternal.java @@ -32,4 +32,9 @@ public interface InputMethodManagerInternal { * Called by the window manager to let the input method manager rotate the input method. */ void switchInputMethod(boolean forwardDirection); + + /** + * Hides the current input method, if visible. + */ + void hideCurrentInputMethod(); } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 727bf5c6bec9a..5d8fe7c68fe8f 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -159,6 +159,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final int MSG_BIND_INPUT = 1010; static final int MSG_SHOW_SOFT_INPUT = 1020; static final int MSG_HIDE_SOFT_INPUT = 1030; + static final int MSG_HIDE_CURRENT_INPUT_METHOD = 1035; static final int MSG_ATTACH_TOKEN = 1040; static final int MSG_CREATE_SESSION = 1050; @@ -2846,6 +2847,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } args.recycle(); return true; + case MSG_HIDE_CURRENT_INPUT_METHOD: + synchronized (mMethodMap) { + hideCurrentInputLocked(0, null); + } + return true; case MSG_ATTACH_TOKEN: args = (SomeArgs)msg.obj; try { @@ -3880,6 +3886,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mHandler.sendMessage(mHandler.obtainMessage(MSG_SWITCH_IME, forwardDirection ? 1 : 0, 0)); } + + @Override + public void hideCurrentInputMethod() { + mHandler.removeMessages(MSG_HIDE_CURRENT_INPUT_METHOD); + mHandler.sendEmptyMessage(MSG_HIDE_CURRENT_INPUT_METHOD); + } } private static String imeWindowStatusToString(final int imeWindowVis) { diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 04d467a3b2759..e73649ddcf3ce 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -45,9 +45,11 @@ import android.view.SurfaceControl; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import android.view.inputmethod.InputMethodManagerInternal; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DockedDividerUtils; +import com.android.server.LocalServices; import com.android.server.wm.DimLayer.DimLayerUser; import com.android.server.wm.WindowManagerService.H; @@ -131,6 +133,7 @@ public class DockedStackDividerController implements DimLayerUser { private float mLastAnimationProgress; private float mLastDividerProgress; private final DividerSnapAlgorithm[] mSnapAlgorithmForRotation = new DividerSnapAlgorithm[4]; + private boolean mImeHideRequested; DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) { mService = service; @@ -375,11 +378,39 @@ public class DockedStackDividerController implements DimLayerUser { } } mDockedStackListeners.finishBroadcast(); - if (!exists) { + if (exists) { + InputMethodManagerInternal inputMethodManagerInternal = + LocalServices.getService(InputMethodManagerInternal.class); + if (inputMethodManagerInternal != null) { + + // Hide the current IME to avoid problems with animations from IME adjustment when + // attaching the docked stack. + inputMethodManagerInternal.hideCurrentInputMethod(); + mImeHideRequested = true; + } + } else { setMinimizedDockedStack(false); } } + /** + * Resets the state that IME hide has been requested. See {@link #isImeHideRequested}. + */ + void resetImeHideRequested() { + mImeHideRequested = false; + } + + /** + * The docked stack divider controller makes sure the IME gets hidden when attaching the docked + * stack, to avoid animation problems. This flag indicates whether the request to hide the IME + * has been sent in an asynchronous manner, and the IME should be treated as hidden already. + * + * @return whether IME hide request has been sent + */ + boolean isImeHideRequested() { + return mImeHideRequested; + } + void notifyDockedStackMinimizedChanged(boolean minimizedDock, long animDuration) { mService.mH.removeMessages(NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED); mService.mH.obtainMessage(NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED, diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 695ed36bb2136..08256e664680a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7596,7 +7596,8 @@ public class WindowManagerService extends IWindowManager.Stub void adjustForImeIfNeeded(final DisplayContent displayContent) { final WindowState imeWin = mInputMethodWindow; - final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw(); + final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw() + && !displayContent.mDividerControllerLocked.isImeHideRequested(); final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID); final TaskStack imeTargetStack = getImeFocusStackLocked(); final int imeDockSide = (dockVisible && imeTargetStack != null) ? diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index f14fd814f5a99..37d6faf5a8464 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1745,6 +1745,10 @@ class WindowStateAnimator { mWin.mAppToken.onFirstWindowDrawn(mWin, this); } + if (mWin.mAttrs.type == TYPE_INPUT_METHOD) { + mWin.mDisplayContent.mDividerControllerLocked.resetImeHideRequested(); + } + return true; } return false;