diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2021-09-13 16:48:09 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-09-13 16:48:09 +0000 |
| commit | 23c4146d0132d4727b4e36a9ae28282ea8c238f5 (patch) | |
| tree | 33cfb90a983317fbbd7e8a07a243d8f1ec03b045 /core/java/android/inputmethodservice | |
| parent | 5b32677ed7bbc5df35774e17fb5c6e09bd6dc8d7 (diff) | |
| parent | 95d4f0dc175f5579e765f49e3b6fa35338b807dc (diff) | |
Merge "Log errors if RemoteInputConnection is used after IMS#onDestroy()"
Diffstat (limited to 'core/java/android/inputmethodservice')
| -rw-r--r-- | core/java/android/inputmethodservice/RemoteInputConnection.java | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/core/java/android/inputmethodservice/RemoteInputConnection.java b/core/java/android/inputmethodservice/RemoteInputConnection.java index 464b421d970d..1065d041713f 100644 --- a/core/java/android/inputmethodservice/RemoteInputConnection.java +++ b/core/java/android/inputmethodservice/RemoteInputConnection.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; import android.os.Handler; +import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; @@ -62,8 +63,29 @@ final class RemoteInputConnection implements InputConnection { @NonNull private final IInputContextInvoker mInvoker; + private static final class InputMethodServiceInternalHolder { + @NonNull + private final WeakReference<InputMethodServiceInternal> mServiceRef; + + private InputMethodServiceInternalHolder( + @NonNull WeakReference<InputMethodServiceInternal> ims) { + mServiceRef = ims; + } + + @AnyThread + @Nullable + public InputMethodServiceInternal getAndWarnIfNull() { + final InputMethodServiceInternal ims = mServiceRef.get(); + if (ims == null) { + Log.e(TAG, "InputMethodService is already destroyed. InputConnection instances" + + " cannot be used beyond InputMethodService lifetime.", new Throwable()); + } + return ims; + } + } + @NonNull - private final WeakReference<InputMethodServiceInternal> mInputMethodService; + private final InputMethodServiceInternalHolder mImsInternal; @MissingMethodFlags private final int mMissingMethods; @@ -81,7 +103,7 @@ final class RemoteInputConnection implements InputConnection { @NonNull WeakReference<InputMethodServiceInternal> inputMethodService, IInputContext inputContext, @MissingMethodFlags int missingMethods, @NonNull CancellationGroup cancellationGroup) { - mInputMethodService = inputMethodService; + mImsInternal = new InputMethodServiceInternalHolder(inputMethodService); mInvoker = IInputContextInvoker.create(inputContext); mMissingMethods = missingMethods; mCancellationGroup = cancellationGroup; @@ -101,11 +123,11 @@ final class RemoteInputConnection implements InputConnection { final CharSequence result = CompletableFutureUtil.getResultOrNull( value, TAG, "getTextAfterCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) { + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal != null && ImeTracing.getInstance().isEnabled()) { final byte[] icProto = InputConnectionProtoDumper.buildGetTextAfterCursorProto(length, flags, result); - inputMethodService.triggerServiceDump(TAG + "#getTextAfterCursor", icProto); + imsInternal.triggerServiceDump(TAG + "#getTextAfterCursor", icProto); } return result; @@ -125,11 +147,11 @@ final class RemoteInputConnection implements InputConnection { final CharSequence result = CompletableFutureUtil.getResultOrNull( value, TAG, "getTextBeforeCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) { + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal != null && ImeTracing.getInstance().isEnabled()) { final byte[] icProto = InputConnectionProtoDumper.buildGetTextBeforeCursorProto(length, flags, result); - inputMethodService.triggerServiceDump(TAG + "#getTextBeforeCursor", icProto); + imsInternal.triggerServiceDump(TAG + "#getTextBeforeCursor", icProto); } return result; @@ -149,11 +171,11 @@ final class RemoteInputConnection implements InputConnection { final CharSequence result = CompletableFutureUtil.getResultOrNull( value, TAG, "getSelectedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) { + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal != null && ImeTracing.getInstance().isEnabled()) { final byte[] icProto = InputConnectionProtoDumper.buildGetSelectedTextProto(flags, result); - inputMethodService.triggerServiceDump(TAG + "#getSelectedText", icProto); + imsInternal.triggerServiceDump(TAG + "#getSelectedText", icProto); } return result; @@ -187,11 +209,11 @@ final class RemoteInputConnection implements InputConnection { final SurroundingText result = CompletableFutureUtil.getResultOrNull( value, TAG, "getSurroundingText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) { + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal != null && ImeTracing.getInstance().isEnabled()) { final byte[] icProto = InputConnectionProtoDumper.buildGetSurroundingTextProto( beforeLength, afterLength, flags, result); - inputMethodService.triggerServiceDump(TAG + "#getSurroundingText", icProto); + imsInternal.triggerServiceDump(TAG + "#getSurroundingText", icProto); } return result; @@ -207,11 +229,11 @@ final class RemoteInputConnection implements InputConnection { final int result = CompletableFutureUtil.getResultOrZero( value, TAG, "getCursorCapsMode()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) { + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal != null && ImeTracing.getInstance().isEnabled()) { final byte[] icProto = InputConnectionProtoDumper.buildGetCursorCapsModeProto( reqModes, result); - inputMethodService.triggerServiceDump(TAG + "#getCursorCapsMode", icProto); + imsInternal.triggerServiceDump(TAG + "#getCursorCapsMode", icProto); } return result; @@ -227,11 +249,11 @@ final class RemoteInputConnection implements InputConnection { final ExtractedText result = CompletableFutureUtil.getResultOrNull( value, TAG, "getExtractedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) { + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal != null && ImeTracing.getInstance().isEnabled()) { final byte[] icProto = InputConnectionProtoDumper.buildGetExtractedTextProto( request, flags, result); - inputMethodService.triggerServiceDump(TAG + "#getExtractedText", icProto); + imsInternal.triggerServiceDump(TAG + "#getExtractedText", icProto); } return result; @@ -248,12 +270,11 @@ final class RemoteInputConnection implements InputConnection { @AnyThread private void notifyUserActionIfNecessary() { - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService == null) { - // This basically should not happen, because it's the the caller of this method. + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal == null) { return; } - inputMethodService.notifyUserActionIfNecessary(); + imsInternal.notifyUserActionIfNecessary(); } @AnyThread @@ -400,12 +421,11 @@ final class RemoteInputConnection implements InputConnection { } if ((flags & InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) { - final InputMethodServiceInternal inputMethodService = mInputMethodService.get(); - if (inputMethodService == null) { - // This basically should not happen, because it's the caller of this method. + final InputMethodServiceInternal imsInternal = mImsInternal.getAndWarnIfNull(); + if (imsInternal == null) { return false; } - inputMethodService.exposeContent(inputContentInfo, this); + imsInternal.exposeContent(inputContentInfo, this); } final CompletableFuture<Boolean> value = |
