From b37f32cfeceb76dd8ae9976575191a5620877dab Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Wed, 4 Aug 2021 11:37:16 -0700 Subject: [PATCH] Let IC#reportFullscreenMode() honor IC#getHandler() This CL fixes a regression that InputConnection#reportFullscreenMode() is always called back on the main thread rather than its associated thread. In most of cases those two threads are the same hence there is no semantic problem, threads are the same, but for some special cases, e.g. when apps explicitly override InputConnection#getHandler(), our thread affinity contract can be violated. This regression was accidentally introduced in Android O time frame while attempting to make the system more robust at Bug 28406127 [1]. Although we have never received any actual issue report from app developers so far, this is still worth fixing. [1]: If23e7c7c265ab3dfb48c2fb6fdb361b17d22c594 2bc66171cce4d5ae7bee2c3920e82e45a9d245af Bug: 28406127 Fix: 193588937 Test: atest CtsInputMethodTestCases:InputConnectionHandlerTest Change-Id: Id3ac21c11d6b062bb66719109376ff642309b8ff --- .../view/inputmethod/InputConnection.java | 11 ++++++++--- .../view/inputmethod/InputMethodManager.java | 6 +++--- .../inputmethod/RemoteInputConnectionImpl.java | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index 5f036a3488083..ccca031aad3f0 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -843,9 +843,14 @@ public interface InputConnection { /** * Called back when the connected IME switches between fullscreen and normal modes. * - *

Note: On {@link android.os.Build.VERSION_CODES#O} and later devices, input methods are no - * longer allowed to directly call this method at any time. To signal this event in the target - * application, input methods should always call + *

Editor authors: There is a bug on + * {@link android.os.Build.VERSION_CODES#O} and later devices that this method is called back + * on the main thread even when {@link #getHandler()} is overridden. This bug is fixed in + * {@link android.os.Build.VERSION_CODES#TIRAMISU}.

+ * + *

IME authors: On {@link android.os.Build.VERSION_CODES#O} and later + * devices, input methods are no longer allowed to directly call this method at any time. + * To signal this event in the target application, input methods should always call * {@link InputMethodService#updateFullscreenMode()} instead. This approach should work on API * {@link android.os.Build.VERSION_CODES#N_MR1} and prior devices.

* diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index c023c6ef04df9..5f659a6afba91 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -950,15 +950,15 @@ public final class InputMethodManager { } case MSG_REPORT_FULLSCREEN_MODE: { final boolean fullscreen = msg.arg1 != 0; - InputConnection ic = null; + RemoteInputConnectionImpl ic = null; synchronized (mH) { if (mFullscreenMode != fullscreen && mServedInputConnection != null) { - ic = mServedInputConnection.getInputConnection(); + ic = mServedInputConnection; mFullscreenMode = fullscreen; } } if (ic != null) { - ic.reportFullscreenMode(fullscreen); + ic.dispatchReportFullscreenMode(fullscreen); } return; } diff --git a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java index d1bca85f8425e..6f79fa117c6a1 100644 --- a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java +++ b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java @@ -169,6 +169,23 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub { } } + /** + * Invoke {@link InputConnection#reportFullscreenMode(boolean)} or schedule it on the target + * thread associated with {@link InputConnection#getHandler()}. + * + * @param enabled the parameter to be passed to + * {@link InputConnection#reportFullscreenMode(boolean)}. + */ + public void dispatchReportFullscreenMode(boolean enabled) { + dispatch(() -> { + final InputConnection ic = getInputConnection(); + if (ic == null || !isActive()) { + return; + } + ic.reportFullscreenMode(enabled); + }); + } + @Override public void getTextAfterCursor(int length, int flags, ICharSequenceResultCallback callback) { dispatch(() -> {