diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index f0b1eaa9f2574..b52b437b45578 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -219,22 +219,29 @@ class IInputMethodWrapper extends IInputMethod.Stub case DO_REVOKE_SESSION: inputMethod.revokeSession((InputMethodSession)msg.obj); return; - case DO_SHOW_SOFT_INPUT: - SomeArgs args = (SomeArgs)msg.obj; + case DO_SHOW_SOFT_INPUT: { + final SomeArgs args = (SomeArgs)msg.obj; inputMethod.showSoftInputWithToken( msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1); + args.recycle(); return; - case DO_HIDE_SOFT_INPUT: - inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj); + } + case DO_HIDE_SOFT_INPUT: { + final SomeArgs args = (SomeArgs) msg.obj; + inputMethod.hideSoftInputWithToken(msg.arg1, (ResultReceiver) args.arg2, + (IBinder) args.arg1); + args.recycle(); return; + } case DO_CHANGE_INPUTMETHOD_SUBTYPE: inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj); return; case DO_CREATE_INLINE_SUGGESTIONS_REQUEST: - args = (SomeArgs) msg.obj; + final SomeArgs args = (SomeArgs) msg.obj; inputMethod.onCreateInlineSuggestionsRequest( (InlineSuggestionsRequestInfo) args.arg1, (IInlineSuggestionsRequestCallback) args.arg2); + args.recycle(); return; } @@ -380,9 +387,9 @@ class IInputMethodWrapper extends IInputMethod.Stub @BinderThread @Override - public void hideSoftInput(int flags, ResultReceiver resultReceiver) { - mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_HIDE_SOFT_INPUT, - flags, resultReceiver)); + public void hideSoftInput(IBinder hideInputToken, int flags, ResultReceiver resultReceiver) { + mCaller.executeOrSendMessage(mCaller.obtainMessageIOO(DO_HIDE_SOFT_INPUT, + flags, hideInputToken, resultReceiver)); } @BinderThread diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 61adfbce30bff..27839e7804944 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -459,6 +459,16 @@ public class InputMethodService extends AbstractInputMethodService { */ private IBinder mCurShowInputToken; + /** + * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#hideSoftInput} + * The original app window token is passed from client app window. + * {@link com.android.server.inputmethod.InputMethodManagerService} creates a unique dummy + * token to identify this window. + * This dummy token is only valid for a single call to {@link InputMethodImpl#hideSoftInput}, + * after which it is set {@code null} until next call. + */ + private IBinder mCurHideInputToken; + final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = info -> { onComputeInsets(mTmpInsets); if (isExtractViewShown()) { @@ -500,6 +510,7 @@ public class InputMethodService extends AbstractInputMethodService { public class InputMethodImpl extends AbstractInputMethodImpl { private boolean mSystemCallingShowSoftInput; + private boolean mSystemCallingHideSoftInput; /** * {@inheritDoc} @@ -634,6 +645,21 @@ public class InputMethodService extends AbstractInputMethodService { } } + /** + * {@inheritDoc} + * @hide + */ + @MainThread + @Override + public void hideSoftInputWithToken(int flags, ResultReceiver resultReceiver, + IBinder hideInputToken) { + mSystemCallingHideSoftInput = true; + mCurHideInputToken = hideInputToken; + hideSoftInput(flags, resultReceiver); + mCurHideInputToken = null; + mSystemCallingHideSoftInput = false; + } + /** * {@inheritDoc} */ @@ -641,6 +667,12 @@ public class InputMethodService extends AbstractInputMethodService { @Override public void hideSoftInput(int flags, ResultReceiver resultReceiver) { if (DEBUG) Log.v(TAG, "hideSoftInput()"); + if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R + && !mSystemCallingHideSoftInput) { + Log.e(TAG, "IME shouldn't call hideSoftInput on itself." + + " Use requestHideSelf(int) itself"); + return; + } final boolean wasVisible = mIsPreRendered ? mDecorViewVisible && mWindowVisible : isInputViewShown(); applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */); @@ -738,6 +770,15 @@ public class InputMethodService extends AbstractInputMethodService { public void setCurrentShowInputToken(IBinder showInputToken) { mCurShowInputToken = showInputToken; } + + /** + * {@inheritDoc} + * @hide + */ + @Override + public void setCurrentHideInputToken(IBinder hideInputToken) { + mCurHideInputToken = hideInputToken; + } } // TODO(b/137800469): Add detailed docs explaining the inline suggestions process. @@ -2172,7 +2213,8 @@ public class InputMethodService extends AbstractInputMethodService { if (!isVisibilityAppliedUsingInsetsConsumer()) { return; } - mPrivOps.applyImeVisibility(mCurShowInputToken, setVisible); + mPrivOps.applyImeVisibility(setVisible + ? mCurShowInputToken : mCurHideInputToken, setVisible); } private boolean isVisibilityAppliedUsingInsetsConsumer() { diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java index 71c9e33d0eeef..869a9295e16b2 100644 --- a/core/java/android/view/inputmethod/InputMethod.java +++ b/core/java/android/view/inputmethod/InputMethod.java @@ -348,6 +348,27 @@ public interface InputMethod { * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN}, * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. + * @param hideInputToken an opaque {@link android.os.Binder} token to identify which API call + * of {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)}} is associated + * with this callback. + * @hide + */ + @MainThread + public void hideSoftInputWithToken(int flags, ResultReceiver resultReceiver, + IBinder hideInputToken); + + /** + * Request that any soft input part of the input method be hidden from the user. + * @param flags Provides additional information about the show request. + * Currently always 0. + * @param resultReceiver The client requesting the show may wish to + * be told the impact of their request, which should be supplied here. + * The result code should be + * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN}, + * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN + * InputMethodManager.RESULT_UNCHANGED_HIDDEN}, + * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or + * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. */ @MainThread public void hideSoftInput(int flags, ResultReceiver resultReceiver); @@ -366,4 +387,13 @@ public interface InputMethod { * @hide */ public void setCurrentShowInputToken(IBinder showInputToken); + + /** + * Update token of the client window requesting {@link #hideSoftInput(int, ResultReceiver)} + * @param hideInputToken dummy app window token for window requesting + * {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)} + * @hide + */ + public void setCurrentHideInputToken(IBinder hideInputToken); + } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 16a45322c9663..f3aa314967c2f 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1709,7 +1709,7 @@ public final class InputMethodManager { } try { - return mService.hideSoftInput(mClient, flags, resultReceiver); + return mService.hideSoftInput(mClient, windowToken, flags, resultReceiver); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1986,7 +1986,8 @@ public final class InputMethodManager { @UnsupportedAppUsage void closeCurrentInput() { try { - mService.hideSoftInput(mClient, HIDE_NOT_ALWAYS, null); + mService.hideSoftInput( + mClient, mCurRootView.getView().getWindowToken(), HIDE_NOT_ALWAYS, null); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl index 20cd7c21d512f..9a226860831ae 100644 --- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl +++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl @@ -41,5 +41,5 @@ interface IInputMethodPrivilegedOperations { boolean shouldOfferSwitchingToNextInputMethod(); void notifyUserAction(); void reportPreRendered(in EditorInfo info); - void applyImeVisibility(IBinder showInputToken, boolean setVisible); + void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible); } diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java index 9eeef963de7f3..e5475f8bea9d1 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java @@ -371,18 +371,20 @@ public final class InputMethodPrivilegedOperations { /** * Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean)}. * - * @param showInputToken dummy token that maps to window requesting - * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} + * @param showOrHideInputToken dummy token that maps to window requesting + * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} or + * {@link android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow + * (IBinder, int)} * @param setVisible {@code true} to set IME visible, else hidden. */ @AnyThread - public void applyImeVisibility(IBinder showInputToken, boolean setVisible) { + public void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible) { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; } try { - ops.applyImeVisibility(showInputToken, setVisible); + ops.applyImeVisibility(showOrHideInputToken, setVisible); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl index fd4b5abe2b210..40e4f4d6ad12e 100644 --- a/core/java/com/android/internal/view/IInputMethod.aidl +++ b/core/java/com/android/internal/view/IInputMethod.aidl @@ -55,7 +55,7 @@ oneway interface IInputMethod { void showSoftInput(in IBinder showInputToken, int flags, in ResultReceiver resultReceiver); - void hideSoftInput(int flags, in ResultReceiver resultReceiver); + void hideSoftInput(in IBinder hideInputToken, int flags, in ResultReceiver resultReceiver); void changeInputMethodSubtype(in InputMethodSubtype subtype); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 0337ddd1ab49f..3f03f2a3e7545 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -43,7 +43,7 @@ interface IInputMethodManager { boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, in ResultReceiver resultReceiver); - boolean hideSoftInput(in IInputMethodClient client, int flags, + boolean hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, in ResultReceiver resultReceiver); // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'attribute' is non-null then also does startInput. diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index e3c545c3cf28a..dcd0a78c01240 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -845,6 +845,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("mMethodMap") private final WeakHashMap mShowRequestWindowMap = new WeakHashMap<>(); + /** + * Map of generated token to windowToken that is requesting + * {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)}. + * This map tracks origin of hideSoftInput requests. + */ + @GuardedBy("mMethodMap") + private final WeakHashMap mHideRequestWindowMap = new WeakHashMap<>(); + /** * A ring buffer to store the history of {@link StartInputInfo}. */ @@ -1064,7 +1072,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub == AccessibilityService.SHOW_MODE_HIDDEN; if (mAccessibilityRequestingNoSoftKeyboard) { final boolean showRequested = mShowRequested; - hideCurrentInputLocked(0, null, + hideCurrentInputLocked(mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE); mShowRequested = showRequested; } else if (mShowRequested) { @@ -1695,7 +1703,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // TODO: Is it really possible that switchUserLocked() happens before system ready? if (mSystemReady) { - hideCurrentInputLocked(0, null, SoftInputShowHideReason.HIDE_SWITCH_USER); + hideCurrentInputLocked( + mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_SWITCH_USER); + resetCurrentMethodAndClient(UnbindReason.SWITCH_USER); buildInputMethodListLocked(initialUserSwitch); if (TextUtils.isEmpty(mSettings.getSelectedInputMethod())) { @@ -3040,7 +3050,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public boolean hideSoftInput(IInputMethodClient client, int flags, + public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, int flags, ResultReceiver resultReceiver) { int uid = Binder.getCallingUid(); synchronized (mMethodMap) { @@ -3068,7 +3078,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } if (DEBUG) Slog.v(TAG, "Client requesting input be hidden"); - return hideCurrentInputLocked(flags, resultReceiver, + return hideCurrentInputLocked(windowToken, flags, resultReceiver, SoftInputShowHideReason.HIDE_SOFT_INPUT); } finally { Binder.restoreCallingIdentity(ident); @@ -3076,7 +3086,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - boolean hideCurrentInputLocked(int flags, ResultReceiver resultReceiver, + boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 && (mShowExplicitlyRequested || mShowForced)) { @@ -3100,12 +3110,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0); boolean res; if (shouldHideSoftInput) { + final Binder hideInputToken = new Binder(); + mHideRequestWindowMap.put(hideInputToken, windowToken); // The IME will report its visible state again after the following message finally // delivered to the IME process as an IPC. Hence the inconsistency between // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in // the final state. - executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(MSG_HIDE_SOFT_INPUT, - reason, mCurMethod, resultReceiver)); + executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(MSG_HIDE_SOFT_INPUT, + reason, mCurMethod, resultReceiver, hideInputToken)); res = true; } else { res = false; @@ -3242,7 +3254,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Slog.w(TAG, "If you need to impersonate a foreground user/profile from" + " a background user, use EditorInfo.targetInputMethodUser with" + " INTERACT_ACROSS_USERS_FULL permission."); - hideCurrentInputLocked(0, null, SoftInputShowHideReason.HIDE_INVALID_USER); + hideCurrentInputLocked( + mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_INVALID_USER); return InputBindResult.INVALID_USER; } @@ -3305,7 +3318,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // be behind any soft input window, so hide the // soft input window if it is shown. if (DEBUG) Slog.v(TAG, "Unspecified window will hide input"); - hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null, + hideCurrentInputLocked( + mCurFocusedWindow, InputMethodManager.HIDE_NOT_ALWAYS, null, SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW); // If focused display changed, we should unbind current method @@ -3342,13 +3356,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub case LayoutParams.SOFT_INPUT_STATE_HIDDEN: if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { if (DEBUG) Slog.v(TAG, "Window asks to hide input going forward"); - hideCurrentInputLocked(0, null, + hideCurrentInputLocked(mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV); } break; case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: if (DEBUG) Slog.v(TAG, "Window asks to hide input"); - hideCurrentInputLocked(0, null, + hideCurrentInputLocked(mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); break; case LayoutParams.SOFT_INPUT_STATE_VISIBLE: @@ -3832,7 +3846,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Send it to window manager to hide IME from IME target window. // TODO(b/139861270): send to mCurClient.client once IMMS is aware of // actual IME target. - mWindowManagerInternal.hideIme(mCurClient.selfReportedDisplayId); + mWindowManagerInternal.hideIme(mHideRequestWindowMap.get(windowToken)); } } else { // Send to window manager to show IME after IME layout finishes. @@ -3872,7 +3886,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } long ident = Binder.clearCallingIdentity(); try { - hideCurrentInputLocked(flags, null, SoftInputShowHideReason.HIDE_MY_SOFT_INPUT); + hideCurrentInputLocked( + mLastImeTargetWindow, flags, null, + SoftInputShowHideReason.HIDE_MY_SOFT_INPUT); + } finally { Binder.restoreCallingIdentity(ident); } @@ -3969,11 +3986,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub args.recycle(); return true; case MSG_SHOW_SOFT_INPUT: - args = (SomeArgs)msg.obj; + args = (SomeArgs) msg.obj; try { final @SoftInputShowHideReason int reason = msg.arg2; if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".showSoftInput(" - + msg.arg1 + ", " + args.arg2 + ") for reason: " + + args.arg3 + ", " + msg.arg1 + ", " + args.arg2 + ") for reason: " + InputMethodDebug.softInputDisplayReasonToString(reason)); ((IInputMethod) args.arg1).showSoftInput( (IBinder) args.arg3, msg.arg1, (ResultReceiver) args.arg2); @@ -3986,13 +4003,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub args.recycle(); return true; case MSG_HIDE_SOFT_INPUT: - args = (SomeArgs)msg.obj; + args = (SomeArgs) msg.obj; try { final @SoftInputShowHideReason int reason = msg.arg1; if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".hideSoftInput(0, " - + args.arg2 + ") for reason: " + + args.arg3 + ", " + args.arg2 + ") for reason: " + InputMethodDebug.softInputDisplayReasonToString(reason)); - ((IInputMethod)args.arg1).hideSoftInput(0, (ResultReceiver)args.arg2); + ((IInputMethod)args.arg1).hideSoftInput( + (IBinder) args.arg3, 0, (ResultReceiver)args.arg2); mSoftInputShowHideHistory.addEntry( new SoftInputShowHideHistory.Entry(mCurClient, InputMethodDebug.objToString(mCurFocusedWindow), @@ -4004,7 +4022,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub case MSG_HIDE_CURRENT_INPUT_METHOD: synchronized (mMethodMap) { final @SoftInputShowHideReason int reason = (int) msg.obj; - hideCurrentInputLocked(0, null, reason); + hideCurrentInputLocked(mCurFocusedWindow, 0, null, reason); + } return true; case MSG_INITIALIZE_IME: @@ -5409,7 +5428,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final String nextIme; final List nextEnabledImes; if (userId == mSettings.getCurrentUserId()) { - hideCurrentInputLocked(0, null, + hideCurrentInputLocked(mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND); unbindCurrentMethodLocked(); // Reset the current IME diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 1aff23b09c0fd..e60b9101fda5a 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1500,7 +1500,8 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override public boolean hideSoftInput( - IInputMethodClient client, int flags, ResultReceiver resultReceiver) { + IInputMethodClient client, IBinder windowToken, int flags, + ResultReceiver resultReceiver) { final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); final int userId = UserHandle.getUserId(callingUid); diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 240f56611c77e..4ac809de29047 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -527,9 +527,9 @@ public abstract class WindowManagerInternal { /** * Hide IME using imeTargetWindow when requested. * - * @param displayId on which IME is shown + * @param imeTargetWindowToken token of the (IME target) window on which IME should be hidden. */ - public abstract void hideIme(int displayId); + public abstract void hideIme(IBinder imeTargetWindowToken); /** * Tell window manager about a package that should not be running with high refresh rate diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index a59eab5959b32..0169a4f758677 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7441,27 +7441,28 @@ public class WindowManagerService extends IWindowManager.Stub return; } imeTarget = imeTarget.getImeControlTarget(); - - final int displayId = imeTarget.getDisplayId(); - mRoot.getDisplayContent(displayId).getInsetsStateController().getImeSourceProvider() + imeTarget.getDisplayContent().getInsetsStateController().getImeSourceProvider() .scheduleShowImePostLayout(imeTarget); } } @Override - public void hideIme(int displayId) { + public void hideIme(IBinder imeTargetWindowToken) { synchronized (mGlobalLock) { - final DisplayContent dc = mRoot.getDisplayContent(displayId); - if (dc != null) { - InsetsControlTarget imeControlTarget = dc.mInputMethodControlTarget; - if (imeControlTarget == null) { - return; - } - // If there was a pending IME show(), reset it as IME has been - // requested to be hidden. - dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout(); - imeControlTarget.hideInsets(WindowInsets.Type.ime(), true /* fromIme */); + WindowState imeTarget = mWindowMap.get(imeTargetWindowToken); + if (imeTarget == null) { + // The target window no longer exists. + return; } + final DisplayContent dc = imeTarget.getImeControlTarget().getDisplayContent(); + // If there was a pending IME show(), reset it as IME has been + // requested to be hidden. + dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout(); + if (dc.mInputMethodControlTarget == null) { + return; + } + dc.mInputMethodControlTarget.hideInsets( + WindowInsets.Type.ime(), true /* fromIme */); } }