summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/inputmethod/ImeTracker.java6
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java21
2 files changed, 26 insertions, 1 deletions
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index d90455ab971d..2ca62a0725df 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -220,6 +220,7 @@ public interface ImeTracker {
PHASE_WM_POSTING_CHANGED_IME_VISIBILITY,
PHASE_WM_INVOKING_IME_REQUESTED_LISTENER,
PHASE_CLIENT_ALREADY_HIDDEN,
+ PHASE_CLIENT_VIEW_HANDLER_AVAILABLE,
})
@Retention(RetentionPolicy.SOURCE)
@interface Phase {}
@@ -424,6 +425,11 @@ public interface ImeTracker {
ImeProtoEnums.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER;
/** IME is requested to be hidden, but already hidden. Don't hide to avoid another animation. */
int PHASE_CLIENT_ALREADY_HIDDEN = ImeProtoEnums.PHASE_CLIENT_ALREADY_HIDDEN;
+ /**
+ * The view's handler is needed to check if we're running on a different thread. We can't
+ * continue without.
+ */
+ int PHASE_CLIENT_VIEW_HANDLER_AVAILABLE = ImeProtoEnums.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE;
/**
* Called when an IME request is started.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 47fc43735c4d..9001251914d6 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2591,6 +2591,17 @@ public final class InputMethodManager {
// TODO(b/322992891) handle case of HIDE_IMPLICIT_ONLY
final var viewRootImpl = servedView.getViewRootImpl();
if (viewRootImpl != null) {
+ Handler vh = servedView.getHandler();
+ if (vh == null) {
+ // If the view doesn't have a handler, something has changed out from
+ // under us. The current input has been closed before (from checkFocus).
+ ImeTracker.forLogging().onFailed(statsToken,
+ ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
+ return false;
+ }
+ ImeTracker.forLogging().onProgress(statsToken,
+ ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
+
if (resultReceiver != null) {
final boolean imeReqVisible =
(viewRootImpl.getInsetsController().getRequestedVisibleTypes()
@@ -2599,7 +2610,15 @@ public final class InputMethodManager {
!imeReqVisible ? InputMethodManager.RESULT_UNCHANGED_HIDDEN
: InputMethodManager.RESULT_HIDDEN, null);
}
- viewRootImpl.getInsetsController().hide(WindowInsets.Type.ime());
+ if (vh.getLooper() != Looper.myLooper()) {
+ // The view is running on a different thread than our own, so
+ // we need to reschedule our work for over there.
+ if (DEBUG) Log.v(TAG, "Hiding soft input: reschedule to view thread");
+ vh.post(() -> viewRootImpl.getInsetsController().hide(
+ WindowInsets.Type.ime()));
+ } else {
+ viewRootImpl.getInsetsController().hide(WindowInsets.Type.ime());
+ }
}
return true;
} else {