Merge "Pipe windowToken for hideSoftInput" into rvc-dev

This commit is contained in:
Taran Singh
2020-02-27 07:14:04 +00:00
committed by Android (Google) Code Review
12 changed files with 158 additions and 55 deletions

View File

@@ -219,22 +219,29 @@ class IInputMethodWrapper extends IInputMethod.Stub
case DO_REVOKE_SESSION: case DO_REVOKE_SESSION:
inputMethod.revokeSession((InputMethodSession)msg.obj); inputMethod.revokeSession((InputMethodSession)msg.obj);
return; return;
case DO_SHOW_SOFT_INPUT: case DO_SHOW_SOFT_INPUT: {
SomeArgs args = (SomeArgs)msg.obj; final SomeArgs args = (SomeArgs)msg.obj;
inputMethod.showSoftInputWithToken( inputMethod.showSoftInputWithToken(
msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1); msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1);
args.recycle();
return; 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; return;
}
case DO_CHANGE_INPUTMETHOD_SUBTYPE: case DO_CHANGE_INPUTMETHOD_SUBTYPE:
inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj); inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj);
return; return;
case DO_CREATE_INLINE_SUGGESTIONS_REQUEST: case DO_CREATE_INLINE_SUGGESTIONS_REQUEST:
args = (SomeArgs) msg.obj; final SomeArgs args = (SomeArgs) msg.obj;
inputMethod.onCreateInlineSuggestionsRequest( inputMethod.onCreateInlineSuggestionsRequest(
(InlineSuggestionsRequestInfo) args.arg1, (InlineSuggestionsRequestInfo) args.arg1,
(IInlineSuggestionsRequestCallback) args.arg2); (IInlineSuggestionsRequestCallback) args.arg2);
args.recycle();
return; return;
} }
@@ -380,9 +387,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
@BinderThread @BinderThread
@Override @Override
public void hideSoftInput(int flags, ResultReceiver resultReceiver) { public void hideSoftInput(IBinder hideInputToken, int flags, ResultReceiver resultReceiver) {
mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_HIDE_SOFT_INPUT, mCaller.executeOrSendMessage(mCaller.obtainMessageIOO(DO_HIDE_SOFT_INPUT,
flags, resultReceiver)); flags, hideInputToken, resultReceiver));
} }
@BinderThread @BinderThread

View File

@@ -459,6 +459,16 @@ public class InputMethodService extends AbstractInputMethodService {
*/ */
private IBinder mCurShowInputToken; 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 -> { final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = info -> {
onComputeInsets(mTmpInsets); onComputeInsets(mTmpInsets);
if (isExtractViewShown()) { if (isExtractViewShown()) {
@@ -500,6 +510,7 @@ public class InputMethodService extends AbstractInputMethodService {
public class InputMethodImpl extends AbstractInputMethodImpl { public class InputMethodImpl extends AbstractInputMethodImpl {
private boolean mSystemCallingShowSoftInput; private boolean mSystemCallingShowSoftInput;
private boolean mSystemCallingHideSoftInput;
/** /**
* {@inheritDoc} * {@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} * {@inheritDoc}
*/ */
@@ -641,6 +667,12 @@ public class InputMethodService extends AbstractInputMethodService {
@Override @Override
public void hideSoftInput(int flags, ResultReceiver resultReceiver) { public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
if (DEBUG) Log.v(TAG, "hideSoftInput()"); 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 final boolean wasVisible = mIsPreRendered
? mDecorViewVisible && mWindowVisible : isInputViewShown(); ? mDecorViewVisible && mWindowVisible : isInputViewShown();
applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */); applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */);
@@ -738,6 +770,15 @@ public class InputMethodService extends AbstractInputMethodService {
public void setCurrentShowInputToken(IBinder showInputToken) { public void setCurrentShowInputToken(IBinder showInputToken) {
mCurShowInputToken = showInputToken; mCurShowInputToken = showInputToken;
} }
/**
* {@inheritDoc}
* @hide
*/
@Override
public void setCurrentHideInputToken(IBinder hideInputToken) {
mCurHideInputToken = hideInputToken;
}
} }
// TODO(b/137800469): Add detailed docs explaining the inline suggestions process. // TODO(b/137800469): Add detailed docs explaining the inline suggestions process.
@@ -2172,7 +2213,8 @@ public class InputMethodService extends AbstractInputMethodService {
if (!isVisibilityAppliedUsingInsetsConsumer()) { if (!isVisibilityAppliedUsingInsetsConsumer()) {
return; return;
} }
mPrivOps.applyImeVisibility(mCurShowInputToken, setVisible); mPrivOps.applyImeVisibility(setVisible
? mCurShowInputToken : mCurHideInputToken, setVisible);
} }
private boolean isVisibilityAppliedUsingInsetsConsumer() { private boolean isVisibilityAppliedUsingInsetsConsumer() {

View File

@@ -348,6 +348,27 @@ public interface InputMethod {
* {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN}, * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN},
* {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or
* {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}. * {@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 @MainThread
public void hideSoftInput(int flags, ResultReceiver resultReceiver); public void hideSoftInput(int flags, ResultReceiver resultReceiver);
@@ -366,4 +387,13 @@ public interface InputMethod {
* @hide * @hide
*/ */
public void setCurrentShowInputToken(IBinder showInputToken); 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);
} }

View File

@@ -1709,7 +1709,7 @@ public final class InputMethodManager {
} }
try { try {
return mService.hideSoftInput(mClient, flags, resultReceiver); return mService.hideSoftInput(mClient, windowToken, flags, resultReceiver);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
@@ -1986,7 +1986,8 @@ public final class InputMethodManager {
@UnsupportedAppUsage @UnsupportedAppUsage
void closeCurrentInput() { void closeCurrentInput() {
try { try {
mService.hideSoftInput(mClient, HIDE_NOT_ALWAYS, null); mService.hideSoftInput(
mClient, mCurRootView.getView().getWindowToken(), HIDE_NOT_ALWAYS, null);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }

View File

@@ -41,5 +41,5 @@ interface IInputMethodPrivilegedOperations {
boolean shouldOfferSwitchingToNextInputMethod(); boolean shouldOfferSwitchingToNextInputMethod();
void notifyUserAction(); void notifyUserAction();
void reportPreRendered(in EditorInfo info); void reportPreRendered(in EditorInfo info);
void applyImeVisibility(IBinder showInputToken, boolean setVisible); void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible);
} }

View File

@@ -371,18 +371,20 @@ public final class InputMethodPrivilegedOperations {
/** /**
* Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean)}. * Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean)}.
* *
* @param showInputToken dummy token that maps to window requesting * @param showOrHideInputToken dummy token that maps to window requesting
* {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} * {@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. * @param setVisible {@code true} to set IME visible, else hidden.
*/ */
@AnyThread @AnyThread
public void applyImeVisibility(IBinder showInputToken, boolean setVisible) { public void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible) {
final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
if (ops == null) { if (ops == null) {
return; return;
} }
try { try {
ops.applyImeVisibility(showInputToken, setVisible); ops.applyImeVisibility(showOrHideInputToken, setVisible);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }

View File

@@ -55,7 +55,7 @@ oneway interface IInputMethod {
void showSoftInput(in IBinder showInputToken, int flags, in ResultReceiver resultReceiver); 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); void changeInputMethodSubtype(in InputMethodSubtype subtype);
} }

View File

@@ -43,7 +43,7 @@ interface IInputMethodManager {
boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
in ResultReceiver resultReceiver); in ResultReceiver resultReceiver);
boolean hideSoftInput(in IInputMethodClient client, int flags, boolean hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
in ResultReceiver resultReceiver); in ResultReceiver resultReceiver);
// If windowToken is null, this just does startInput(). Otherwise this reports that a window // 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. // has gained focus, and if 'attribute' is non-null then also does startInput.

View File

@@ -845,6 +845,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("mMethodMap") @GuardedBy("mMethodMap")
private final WeakHashMap<IBinder, IBinder> mShowRequestWindowMap = new WeakHashMap<>(); private final WeakHashMap<IBinder, IBinder> 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<IBinder, IBinder> mHideRequestWindowMap = new WeakHashMap<>();
/** /**
* A ring buffer to store the history of {@link StartInputInfo}. * A ring buffer to store the history of {@link StartInputInfo}.
*/ */
@@ -1064,7 +1072,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
== AccessibilityService.SHOW_MODE_HIDDEN; == AccessibilityService.SHOW_MODE_HIDDEN;
if (mAccessibilityRequestingNoSoftKeyboard) { if (mAccessibilityRequestingNoSoftKeyboard) {
final boolean showRequested = mShowRequested; final boolean showRequested = mShowRequested;
hideCurrentInputLocked(0, null, hideCurrentInputLocked(mCurFocusedWindow, 0, null,
SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE); SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE);
mShowRequested = showRequested; mShowRequested = showRequested;
} else if (mShowRequested) { } else if (mShowRequested) {
@@ -1695,7 +1703,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// TODO: Is it really possible that switchUserLocked() happens before system ready? // TODO: Is it really possible that switchUserLocked() happens before system ready?
if (mSystemReady) { if (mSystemReady) {
hideCurrentInputLocked(0, null, SoftInputShowHideReason.HIDE_SWITCH_USER); hideCurrentInputLocked(
mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_SWITCH_USER);
resetCurrentMethodAndClient(UnbindReason.SWITCH_USER); resetCurrentMethodAndClient(UnbindReason.SWITCH_USER);
buildInputMethodListLocked(initialUserSwitch); buildInputMethodListLocked(initialUserSwitch);
if (TextUtils.isEmpty(mSettings.getSelectedInputMethod())) { if (TextUtils.isEmpty(mSettings.getSelectedInputMethod())) {
@@ -3040,7 +3050,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
@Override @Override
public boolean hideSoftInput(IInputMethodClient client, int flags, public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver) { ResultReceiver resultReceiver) {
int uid = Binder.getCallingUid(); int uid = Binder.getCallingUid();
synchronized (mMethodMap) { synchronized (mMethodMap) {
@@ -3068,7 +3078,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
if (DEBUG) Slog.v(TAG, "Client requesting input be hidden"); if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
return hideCurrentInputLocked(flags, resultReceiver, return hideCurrentInputLocked(windowToken, flags, resultReceiver,
SoftInputShowHideReason.HIDE_SOFT_INPUT); SoftInputShowHideReason.HIDE_SOFT_INPUT);
} finally { } finally {
Binder.restoreCallingIdentity(ident); 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) { @SoftInputShowHideReason int reason) {
if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
&& (mShowExplicitlyRequested || mShowForced)) { && (mShowExplicitlyRequested || mShowForced)) {
@@ -3100,12 +3110,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
(mImeWindowVis & InputMethodService.IME_ACTIVE) != 0); (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
boolean res; boolean res;
if (shouldHideSoftInput) { if (shouldHideSoftInput) {
final Binder hideInputToken = new Binder();
mHideRequestWindowMap.put(hideInputToken, windowToken);
// The IME will report its visible state again after the following message finally // 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 // delivered to the IME process as an IPC. Hence the inconsistency between
// IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
// the final state. // the final state.
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(MSG_HIDE_SOFT_INPUT, executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(MSG_HIDE_SOFT_INPUT,
reason, mCurMethod, resultReceiver)); reason, mCurMethod, resultReceiver, hideInputToken));
res = true; res = true;
} else { } else {
res = false; 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" Slog.w(TAG, "If you need to impersonate a foreground user/profile from"
+ " a background user, use EditorInfo.targetInputMethodUser with" + " a background user, use EditorInfo.targetInputMethodUser with"
+ " INTERACT_ACROSS_USERS_FULL permission."); + " INTERACT_ACROSS_USERS_FULL permission.");
hideCurrentInputLocked(0, null, SoftInputShowHideReason.HIDE_INVALID_USER); hideCurrentInputLocked(
mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_INVALID_USER);
return InputBindResult.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 // be behind any soft input window, so hide the
// soft input window if it is shown. // soft input window if it is shown.
if (DEBUG) Slog.v(TAG, "Unspecified window will hide input"); 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); SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW);
// If focused display changed, we should unbind current method // 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: case LayoutParams.SOFT_INPUT_STATE_HIDDEN:
if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
if (DEBUG) Slog.v(TAG, "Window asks to hide input going forward"); 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); SoftInputShowHideReason.HIDE_STATE_HIDDEN_FORWARD_NAV);
} }
break; break;
case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
if (DEBUG) Slog.v(TAG, "Window asks to hide input"); if (DEBUG) Slog.v(TAG, "Window asks to hide input");
hideCurrentInputLocked(0, null, hideCurrentInputLocked(mCurFocusedWindow, 0, null,
SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE);
break; break;
case LayoutParams.SOFT_INPUT_STATE_VISIBLE: 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. // Send it to window manager to hide IME from IME target window.
// TODO(b/139861270): send to mCurClient.client once IMMS is aware of // TODO(b/139861270): send to mCurClient.client once IMMS is aware of
// actual IME target. // actual IME target.
mWindowManagerInternal.hideIme(mCurClient.selfReportedDisplayId); mWindowManagerInternal.hideIme(mHideRequestWindowMap.get(windowToken));
} }
} else { } else {
// Send to window manager to show IME after IME layout finishes. // 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(); long ident = Binder.clearCallingIdentity();
try { try {
hideCurrentInputLocked(flags, null, SoftInputShowHideReason.HIDE_MY_SOFT_INPUT); hideCurrentInputLocked(
mLastImeTargetWindow, flags, null,
SoftInputShowHideReason.HIDE_MY_SOFT_INPUT);
} finally { } finally {
Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident);
} }
@@ -3969,11 +3986,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
args.recycle(); args.recycle();
return true; return true;
case MSG_SHOW_SOFT_INPUT: case MSG_SHOW_SOFT_INPUT:
args = (SomeArgs)msg.obj; args = (SomeArgs) msg.obj;
try { try {
final @SoftInputShowHideReason int reason = msg.arg2; final @SoftInputShowHideReason int reason = msg.arg2;
if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".showSoftInput(" 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)); + InputMethodDebug.softInputDisplayReasonToString(reason));
((IInputMethod) args.arg1).showSoftInput( ((IInputMethod) args.arg1).showSoftInput(
(IBinder) args.arg3, msg.arg1, (ResultReceiver) args.arg2); (IBinder) args.arg3, msg.arg1, (ResultReceiver) args.arg2);
@@ -3986,13 +4003,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
args.recycle(); args.recycle();
return true; return true;
case MSG_HIDE_SOFT_INPUT: case MSG_HIDE_SOFT_INPUT:
args = (SomeArgs)msg.obj; args = (SomeArgs) msg.obj;
try { try {
final @SoftInputShowHideReason int reason = msg.arg1; final @SoftInputShowHideReason int reason = msg.arg1;
if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".hideSoftInput(0, " if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".hideSoftInput(0, "
+ args.arg2 + ") for reason: " + args.arg3 + ", " + args.arg2 + ") for reason: "
+ InputMethodDebug.softInputDisplayReasonToString(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( mSoftInputShowHideHistory.addEntry(
new SoftInputShowHideHistory.Entry(mCurClient, new SoftInputShowHideHistory.Entry(mCurClient,
InputMethodDebug.objToString(mCurFocusedWindow), InputMethodDebug.objToString(mCurFocusedWindow),
@@ -4004,7 +4022,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
case MSG_HIDE_CURRENT_INPUT_METHOD: case MSG_HIDE_CURRENT_INPUT_METHOD:
synchronized (mMethodMap) { synchronized (mMethodMap) {
final @SoftInputShowHideReason int reason = (int) msg.obj; final @SoftInputShowHideReason int reason = (int) msg.obj;
hideCurrentInputLocked(0, null, reason); hideCurrentInputLocked(mCurFocusedWindow, 0, null, reason);
} }
return true; return true;
case MSG_INITIALIZE_IME: case MSG_INITIALIZE_IME:
@@ -5409,7 +5428,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final String nextIme; final String nextIme;
final List<InputMethodInfo> nextEnabledImes; final List<InputMethodInfo> nextEnabledImes;
if (userId == mSettings.getCurrentUserId()) { if (userId == mSettings.getCurrentUserId()) {
hideCurrentInputLocked(0, null, hideCurrentInputLocked(mCurFocusedWindow, 0, null,
SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND); SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
unbindCurrentMethodLocked(); unbindCurrentMethodLocked();
// Reset the current IME // Reset the current IME

View File

@@ -1500,7 +1500,8 @@ public final class MultiClientInputMethodManagerService {
@BinderThread @BinderThread
@Override @Override
public boolean hideSoftInput( public boolean hideSoftInput(
IInputMethodClient client, int flags, ResultReceiver resultReceiver) { IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver) {
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid(); final int callingPid = Binder.getCallingPid();
final int userId = UserHandle.getUserId(callingUid); final int userId = UserHandle.getUserId(callingUid);

View File

@@ -527,9 +527,9 @@ public abstract class WindowManagerInternal {
/** /**
* Hide IME using imeTargetWindow when requested. * 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 * Tell window manager about a package that should not be running with high refresh rate

View File

@@ -7441,27 +7441,28 @@ public class WindowManagerService extends IWindowManager.Stub
return; return;
} }
imeTarget = imeTarget.getImeControlTarget(); imeTarget = imeTarget.getImeControlTarget();
imeTarget.getDisplayContent().getInsetsStateController().getImeSourceProvider()
final int displayId = imeTarget.getDisplayId();
mRoot.getDisplayContent(displayId).getInsetsStateController().getImeSourceProvider()
.scheduleShowImePostLayout(imeTarget); .scheduleShowImePostLayout(imeTarget);
} }
} }
@Override @Override
public void hideIme(int displayId) { public void hideIme(IBinder imeTargetWindowToken) {
synchronized (mGlobalLock) { synchronized (mGlobalLock) {
final DisplayContent dc = mRoot.getDisplayContent(displayId); WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
if (dc != null) { if (imeTarget == null) {
InsetsControlTarget imeControlTarget = dc.mInputMethodControlTarget; // The target window no longer exists.
if (imeControlTarget == null) { return;
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 */);
} }
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 */);
} }
} }