From 4fe5b654a1e420fd66781b09223a1c25f9a06aeb Mon Sep 17 00:00:00 2001 From: Tarandeep Singh Date: Thu, 20 Feb 2020 17:20:19 -0800 Subject: Pipe windowToken for hideSoftInput Pipe the windowToken of the window requesting hideSoftInput just like we did it for showSoftInput [1]. This calls hideInsets on the correct display when control target is different from IME target e.g. ActivityView. Also hideInsets should be called on InsetsControlTarget instead which was originally attempted in [2] [1]: Ia49e23dd077d264a58d28a7b8acffde54b7db187 [2]: I7133e151a1037c42b275b97857936437a7a6725f Bug: 149870112 Bug: 133381284 Test: Manually using steps mentioned in bug. Change-Id: Ia596a392eb73ae46debd097151c8c9a7edd59833 --- .../inputmethodservice/InputMethodService.java | 44 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'core/java/android/inputmethodservice/InputMethodService.java') diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 20a4ab35defe..45aea4f3d8fc 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. @@ -2157,7 +2198,8 @@ public class InputMethodService extends AbstractInputMethodService { if (!isVisibilityAppliedUsingInsetsConsumer()) { return; } - mPrivOps.applyImeVisibility(mCurShowInputToken, setVisible); + mPrivOps.applyImeVisibility(setVisible + ? mCurShowInputToken : mCurHideInputToken, setVisible); } private boolean isVisibilityAppliedUsingInsetsConsumer() { -- cgit v1.2.3