From 1ab4cb2da6e33e2bf25c0e535e01233ce367331e Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 30 Sep 2021 13:13:56 -0700 Subject: Fix InputMethodServiceInternal lifetime This is a follow up CL to my recent CL [1], which aimed to consolidate dependencies on InputMethodService from RemoteInputConnection. One thing I overlooked was that InputMethodService did not retain a strong reference to InputMethodServiceInternal object that I introduced there, which means that the newly instantiated InputMethodServiceInternal could be garbage-collected even before InputMethodService became unreachable. As a result, the following InputConnection APIs could start failing at some point and would never work without restarting the IME, which is likely to be the root cause of the recent flakiness in InputConnectionEndToEndTest discussed in Bug 193822485. * InputConnection#requestCursorUpdates() * InputConnection#commitContent() Also, the following functionality might have stopped working at some point. * InputMethodService#dump() * InputConnection tracing in IME tracing * Updating IME switching order based on user inputs With this CL, the InputMethodServiceInternal instance is guaranteed to be instantiated once and remain to be alive until AbstractInputMethodService becomes unreachable. [1]: I2aeeeacd27195ce10059d6590e098a4a969e774d a975bfc447b04fe90a5ec9c3d4757810f7d07af1 Fix: 193822485 Fix: 199288389 Test: atest CtsInputMethodTestCases Test: Manually verified with Imege Keyboard sample IME/app Change-Id: I7ee0270bad94ed606048bfaf76e8545336715d83 --- .../inputmethodservice/AbstractInputMethodService.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'core/java/android/inputmethodservice/AbstractInputMethodService.java') diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java index a6e77023790c..4ecd15e002ef 100644 --- a/core/java/android/inputmethodservice/AbstractInputMethodService.java +++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java @@ -66,7 +66,17 @@ import java.io.PrintWriter; public abstract class AbstractInputMethodService extends WindowProviderService implements KeyEvent.Callback { private InputMethod mInputMethod; - + + /** + * Keep the strong reference to {@link InputMethodServiceInternal} to ensure that it will not be + * garbage-collected until {@link AbstractInputMethodService} gets garbage-collected. + * + *

This is necessary because {@link RemoteInputConnection} internally uses + * {@link java.lang.ref.WeakReference} to hold {@link InputMethodServiceInternal}.

+ */ + @Nullable + private InputMethodServiceInternal mInputMethodServiceInternal; + final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState(); @@ -225,7 +235,10 @@ public abstract class AbstractInputMethodService extends WindowProviderService if (mInputMethod == null) { mInputMethod = onCreateInputMethodInterface(); } - return new IInputMethodWrapper(createInputMethodServiceInternal(), mInputMethod); + if (mInputMethodServiceInternal == null) { + mInputMethodServiceInternal = createInputMethodServiceInternal(); + } + return new IInputMethodWrapper(mInputMethodServiceInternal, mInputMethod); } /** -- cgit v1.2.3