summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Felix Stern <fstern@google.com> 2024-10-23 14:48:50 +0000
committer Felix Stern <fstern@google.com> 2024-10-23 14:52:10 +0000
commit8cd5cb68e195acb7ef34e8d1852fcc6cfd388f2d (patch)
tree71b88ec892101567655ad8c59f8a63b5773ac3ed
parent7875655e9f772f175bc57799a88917101571649a (diff)
Fix a race when an editText was removed and added immediately again
In some rare cases, the hide request that was triggered by removing a view was applied in InsetsController too late. A following show request could have been applied before, resulting in the IME not being shown. This was caused by InputMethodManager, as some methods (e.g., closeCurrentInput()) did not call into InsetsController#hide, but into IMMS. This CL fixes this race condition by calling directly into InsetsController#hide, instead of using IInputMethodManagerGlobalInvoker. Test: atest WindowInsetsControllerTests#testShowIme_immediatelyAfterDetachAndReattach --rerun-until-failure 100 Fix: 373971329 Flag: android.view.inputmethod.refactor_insets_controller Change-Id: Ib2dc444d3d08b23e36df1c2c72e630115804f80f
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java48
1 files changed, 31 insertions, 17 deletions
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 47fc43735c4d..d34f86c8e0d7 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2557,21 +2557,24 @@ public final class InputMethodManager {
public boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags,
ResultReceiver resultReceiver) {
return hideSoftInputFromWindow(windowToken, flags, resultReceiver,
- SoftInputShowHideReason.HIDE_SOFT_INPUT);
+ SoftInputShowHideReason.HIDE_SOFT_INPUT, null);
}
private boolean hideSoftInputFromWindow(IBinder windowToken, @HideFlags int flags,
- ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+ ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
+ @Nullable ImeTracker.Token statsToken) {
// Get served view initially for statsToken creation.
final View initialServedView;
synchronized (mH) {
initialServedView = getServedViewLocked();
}
- final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
- ImeTracker.ORIGIN_CLIENT, reason, ImeTracker.isFromUser(initialServedView));
- ImeTracker.forLatency().onRequestHide(statsToken,
- ImeTracker.ORIGIN_CLIENT, reason, ActivityThread::currentApplication);
+ if (statsToken == null) {
+ statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
+ ImeTracker.ORIGIN_CLIENT, reason, ImeTracker.isFromUser(initialServedView));
+ ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT, reason,
+ ActivityThread::currentApplication);
+ }
ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
this, null /* icProto */);
checkFocus();
@@ -2646,8 +2649,14 @@ public final class InputMethodManager {
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
- return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, view.getWindowToken(),
- statsToken, flags, null, reason, mAsyncShowHideMethodEnabled);
+ if (Flags.refactorInsetsController()) {
+ return hideSoftInputFromWindow(view.getWindowToken(), flags,
+ null /* resultReceiver */, reason, statsToken);
+ } else {
+ return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient,
+ view.getWindowToken(), statsToken, flags, null, reason,
+ mAsyncShowHideMethodEnabled);
+ }
}
}
@@ -3143,7 +3152,7 @@ public final class InputMethodManager {
if (rootInsets != null && rootInsets.isVisible(WindowInsets.Type.ime())) {
hideSoftInputFromWindow(view.getWindowToken(), hideFlags,
null /* resultReceiver */,
- SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT);
+ SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT, null);
} else {
showSoftInput(view, showFlags, null /* resultReceiver */,
SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT);
@@ -3721,14 +3730,19 @@ public final class InputMethodManager {
ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
- IInputMethodManagerGlobalInvoker.hideSoftInput(
- mClient,
- rootView.getWindowToken(),
- statsToken,
- HIDE_NOT_ALWAYS,
- null,
- reason,
- true /*async */);
+ if (Flags.refactorInsetsController()) {
+ mCurRootView.getInsetsController().hide(WindowInsets.Type.ime(),
+ false /* fromIme */, statsToken);
+ } else {
+ IInputMethodManagerGlobalInvoker.hideSoftInput(
+ mClient,
+ rootView.getWindowToken(),
+ statsToken,
+ HIDE_NOT_ALWAYS,
+ null,
+ reason,
+ true /*async */);
+ }
}
}