From cdd13118affcb41d7e2df206e887ea2cc50b067f Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Wed, 30 Jun 2021 09:54:14 -0700 Subject: [PATCH] Introduce IInputContextInvoker for better readability This is a purely mechanical refactoring with no no behavior change. With this CL, InputConnectionWrapper no longer deals with boilerplate code around IInputContext such as RemoteException handling. Bug: 192412909 Test: atest CtsInputMethodTestCases Change-Id: I0ea27e915a07699a4c124750266d84346fbd7bf6 --- .../inputmethod/IInputContextInvoker.java | 532 ++++++++++++++++++ .../internal/view/InputConnectionWrapper.java | 217 ++----- 2 files changed, 577 insertions(+), 172 deletions(-) create mode 100644 core/java/com/android/internal/inputmethod/IInputContextInvoker.java diff --git a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java new file mode 100644 index 0000000000000..2ad1373b07b08 --- /dev/null +++ b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.inputmethod; + +import android.annotation.AnyThread; +import android.annotation.NonNull; +import android.os.Bundle; +import android.os.RemoteException; +import android.view.KeyEvent; +import android.view.inputmethod.CompletionInfo; +import android.view.inputmethod.CorrectionInfo; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputContentInfo; + +import com.android.internal.view.IInputContext; + +import java.util.Objects; + +/** + * A stateless wrapper of {@link com.android.internal.view.IInputContext} to encapsulate boilerplate + * code around {@link Completable} and {@link RemoteException}. + */ +public final class IInputContextInvoker { + + @NonNull + private final IInputContext mIInputContext; + + private IInputContextInvoker(@NonNull IInputContext inputContext) { + mIInputContext = inputContext; + } + + /** + * Creates a new instance of {@link IInputContextInvoker} for the given {@link IInputContext}. + * + * @param inputContext {@link IInputContext} to be wrapped. + * @return A new instance of {@link IInputContextInvoker}. + */ + public static IInputContextInvoker create(@NonNull IInputContext inputContext) { + Objects.requireNonNull(inputContext); + return new IInputContextInvoker(inputContext); + } + + /** + * Invokes {@link IInputContext#getTextAfterCursor(int, int, + * com.android.internal.inputmethod.ICharSequenceResultCallback)}. + * + * @param length {@code length} parameter to be passed. + * @param flags {@code flags} parameter to be passed. + * @return {@link Completable.CharSequence} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.CharSequence getTextAfterCursor(int length, int flags) { + final Completable.CharSequence value = Completable.createCharSequence(); + try { + mIInputContext.getTextAfterCursor(length, flags, ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes {@link IInputContext#getTextBeforeCursor(int, int, ICharSequenceResultCallback)}. + * + * @param length {@code length} parameter to be passed. + * @param flags {@code flags} parameter to be passed. + * @return {@link Completable.CharSequence} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.CharSequence getTextBeforeCursor(int length, int flags) { + final Completable.CharSequence value = Completable.createCharSequence(); + try { + mIInputContext.getTextBeforeCursor(length, flags, ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes {@link IInputContext#getSelectedText(int, ICharSequenceResultCallback)}. + * + * @param flags {@code flags} parameter to be passed. + * @return {@link Completable.CharSequence} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.CharSequence getSelectedText(int flags) { + final Completable.CharSequence value = Completable.createCharSequence(); + try { + mIInputContext.getSelectedText(flags, ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes + * {@link IInputContext#getSurroundingText(int, int, int, ISurroundingTextResultCallback)}. + * + * @param beforeLength {@code beforeLength} parameter to be passed. + * @param afterLength {@code afterLength} parameter to be passed. + * @param flags {@code flags} parameter to be passed. + * @return {@link Completable.SurroundingText} that can be used to retrieve the invocation + * result. {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.SurroundingText getSurroundingText(int beforeLength, int afterLength, + int flags) { + final Completable.SurroundingText value = Completable.createSurroundingText(); + try { + mIInputContext.getSurroundingText(beforeLength, afterLength, flags, + ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes {@link IInputContext#getCursorCapsMode(int, IIntResultCallback)}. + * + * @param reqModes {@code reqModes} parameter to be passed. + * @return {@link Completable.Int} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.Int getCursorCapsMode(int reqModes) { + final Completable.Int value = Completable.createInt(); + try { + mIInputContext.getCursorCapsMode(reqModes, ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes {@link IInputContext#getExtractedText(ExtractedTextRequest, int, + * IExtractedTextResultCallback)}. + * + * @param request {@code request} parameter to be passed. + * @param flags {@code flags} parameter to be passed. + * @return {@link Completable.ExtractedText} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { + final Completable.ExtractedText value = Completable.createExtractedText(); + try { + mIInputContext.getExtractedText(request, flags, ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes {@link IInputContext#commitText(CharSequence, int)}. + * + * @param text {@code text} parameter to be passed. + * @param newCursorPosition {@code newCursorPosition} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean commitText(CharSequence text, int newCursorPosition) { + try { + mIInputContext.commitText(text, newCursorPosition); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#commitCompletion(CompletionInfo)}. + * + * @param text {@code text} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean commitCompletion(CompletionInfo text) { + try { + mIInputContext.commitCompletion(text); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#commitCorrection(CorrectionInfo)}. + * + * @param correctionInfo {@code correctionInfo} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean commitCorrection(CorrectionInfo correctionInfo) { + try { + mIInputContext.commitCorrection(correctionInfo); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#setSelection(int, int)}. + * + * @param start {@code start} parameter to be passed. + * @param end {@code start} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean setSelection(int start, int end) { + try { + mIInputContext.setSelection(start, end); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#performEditorAction(int)}. + * + * @param actionCode {@code start} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean performEditorAction(int actionCode) { + try { + mIInputContext.performEditorAction(actionCode); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#performContextMenuAction(id)}. + * + * @param id {@code id} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean performContextMenuAction(int id) { + try { + mIInputContext.performContextMenuAction(id); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#setComposingRegion(int, int)}. + * + * @param start {@code id} parameter to be passed. + * @param end {@code id} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean setComposingRegion(int start, int end) { + try { + mIInputContext.setComposingRegion(start, end); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#setComposingText(CharSequence, int)}. + * + * @param text {@code text} parameter to be passed. + * @param newCursorPosition {@code newCursorPosition} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean setComposingText(CharSequence text, int newCursorPosition) { + try { + mIInputContext.setComposingText(text, newCursorPosition); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#finishComposingText()}. + * + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean finishComposingText() { + try { + mIInputContext.finishComposingText(); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#beginBatchEdit()}. + * + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean beginBatchEdit() { + try { + mIInputContext.beginBatchEdit(); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#endBatchEdit()}. + * + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean endBatchEdit() { + try { + mIInputContext.endBatchEdit(); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#sendKeyEvent(KeyEvent)}. + * + * @param event {@code event} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean sendKeyEvent(KeyEvent event) { + try { + mIInputContext.sendKeyEvent(event); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#clearMetaKeyStates(int)}. + * + * @param states {@code states} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean clearMetaKeyStates(int states) { + try { + mIInputContext.clearMetaKeyStates(states); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#deleteSurroundingText(int, int)}. + * + * @param beforeLength {@code beforeLength} parameter to be passed. + * @param afterLength {@code afterLength} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean deleteSurroundingText(int beforeLength, int afterLength) { + try { + mIInputContext.deleteSurroundingText(beforeLength, afterLength); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#deleteSurroundingTextInCodePoints(int, int)}. + * + * @param beforeLength {@code beforeLength} parameter to be passed. + * @param afterLength {@code afterLength} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) { + try { + mIInputContext.deleteSurroundingTextInCodePoints(beforeLength, afterLength); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#performSpellCheck()}. + * + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean performSpellCheck() { + try { + mIInputContext.performSpellCheck(); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#performPrivateCommand(String, Bundle)}. + * + * @param action {@code action} parameter to be passed. + * @param data {@code data} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean performPrivateCommand(String action, Bundle data) { + try { + mIInputContext.performPrivateCommand(action, data); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Invokes {@link IInputContext#requestUpdateCursorAnchorInfo(int, IIntResultCallback)}. + * + * @param cursorUpdateMode {@code cursorUpdateMode} parameter to be passed. + * @return {@link Completable.Int} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.Int requestUpdateCursorAnchorInfo(int cursorUpdateMode) { + final Completable.Int value = Completable.createInt(); + try { + mIInputContext.requestUpdateCursorAnchorInfo(cursorUpdateMode, + ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes + * {@link IInputContext#commitContent(InputContentInfo, int, Bundle, IIntResultCallback)}. + * + * @param inputContentInfo {@code inputContentInfo} parameter to be passed. + * @param flags {@code flags} parameter to be passed. + * @param opts {@code opts} parameter to be passed. + * @return {@link Completable.Int} that can be used to retrieve the invocation result. + * {@link RemoteException} will be treated as an error. + */ + @AnyThread + @NonNull + public Completable.Int commitContent(InputContentInfo inputContentInfo, int flags, + Bundle opts) { + final Completable.Int value = Completable.createInt(); + try { + mIInputContext.commitContent(inputContentInfo, flags, opts, ResultCallbacks.of(value)); + } catch (RemoteException e) { + value.onError(ThrowableHolder.of(e)); + } + return value; + } + + /** + * Invokes {@link IInputContext#setImeConsumesInput(boolean)}. + * + * @param imeConsumesInput {@code imeConsumesInput} parameter to be passed. + * @return {@code true} if the invocation is completed without {@link RemoteException}. + * {@code false} otherwise. + */ + @AnyThread + public boolean setImeConsumesInput(boolean imeConsumesInput) { + try { + mIInputContext.setImeConsumesInput(imeConsumesInput); + return true; + } catch (RemoteException e) { + return false; + } + } +} diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index 5493a5c36972e..0f366f183e6cf 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -23,7 +23,6 @@ import android.annotation.Nullable; import android.inputmethodservice.AbstractInputMethodService; import android.os.Bundle; import android.os.Handler; -import android.os.RemoteException; import android.util.imetracing.ImeTracing; import android.util.imetracing.InputConnectionHelper; import android.util.proto.ProtoOutputStream; @@ -40,7 +39,7 @@ import android.view.inputmethod.SurroundingText; import com.android.internal.inputmethod.CancellationGroup; import com.android.internal.inputmethod.Completable; -import com.android.internal.inputmethod.ResultCallbacks; +import com.android.internal.inputmethod.IInputContextInvoker; import java.lang.ref.WeakReference; @@ -48,7 +47,10 @@ public class InputConnectionWrapper implements InputConnection { private static final String TAG = "InputConnectionWrapper"; private static final int MAX_WAIT_TIME_MILLIS = 2000; - private final IInputContext mIInputContext; + + @NonNull + private final IInputContextInvoker mInvoker; + @NonNull private final WeakReference mInputMethodService; @@ -69,7 +71,7 @@ public class InputConnectionWrapper implements InputConnection { IInputContext inputContext, @MissingMethodFlags int missingMethods, @NonNull CancellationGroup cancellationGroup) { mInputMethodService = inputMethodService; - mIInputContext = inputContext; + mInvoker = IInputContextInvoker.create(inputContext); mMissingMethods = missingMethods; mCancellationGroup = cancellationGroup; } @@ -84,14 +86,8 @@ public class InputConnectionWrapper implements InputConnection { return null; } - final Completable.CharSequence value = Completable.createCharSequence(); - boolean hadRemoteException = false; - try { - mIInputContext.getTextAfterCursor(length, flags, ResultCallbacks.of(value)); - } catch (RemoteException e) { - hadRemoteException = true; - } - final CharSequence result = hadRemoteException ? null : Completable.getResultOrNull( + final Completable.CharSequence value = mInvoker.getTextAfterCursor(length, flags); + final CharSequence result = Completable.getResultOrNull( value, TAG, "getTextAfterCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); final AbstractInputMethodService inputMethodService = mInputMethodService.get(); @@ -115,14 +111,8 @@ public class InputConnectionWrapper implements InputConnection { return null; } - final Completable.CharSequence value = Completable.createCharSequence(); - boolean hadRemoteException = false; - try { - mIInputContext.getTextBeforeCursor(length, flags, ResultCallbacks.of(value)); - } catch (RemoteException e) { - hadRemoteException = true; - } - final CharSequence result = hadRemoteException ? null : Completable.getResultOrNull( + final Completable.CharSequence value = mInvoker.getTextBeforeCursor(length, flags); + final CharSequence result = Completable.getResultOrNull( value, TAG, "getTextBeforeCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); final AbstractInputMethodService inputMethodService = mInputMethodService.get(); @@ -146,14 +136,8 @@ public class InputConnectionWrapper implements InputConnection { // This method is not implemented. return null; } - final Completable.CharSequence value = Completable.createCharSequence(); - boolean hadRemoteException = false; - try { - mIInputContext.getSelectedText(flags, ResultCallbacks.of(value)); - } catch (RemoteException e) { - hadRemoteException = true; - } - final CharSequence result = hadRemoteException ? null : Completable.getResultOrNull( + final Completable.CharSequence value = mInvoker.getSelectedText(flags); + final CharSequence result = Completable.getResultOrNull( value, TAG, "getSelectedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); final AbstractInputMethodService inputMethodService = mInputMethodService.get(); @@ -190,15 +174,9 @@ public class InputConnectionWrapper implements InputConnection { // This method is not implemented. return null; } - final Completable.SurroundingText value = Completable.createSurroundingText(); - boolean hadRemoteException = false; - try { - mIInputContext.getSurroundingText(beforeLength, afterLength, flags, - ResultCallbacks.of(value)); - } catch (RemoteException e) { - hadRemoteException = true; - } - final SurroundingText result = hadRemoteException ? null : Completable.getResultOrNull( + final Completable.SurroundingText value = mInvoker.getSurroundingText(beforeLength, + afterLength, flags); + final SurroundingText result = Completable.getResultOrNull( value, TAG, "getSurroundingText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); final AbstractInputMethodService inputMethodService = mInputMethodService.get(); @@ -218,14 +196,8 @@ public class InputConnectionWrapper implements InputConnection { return 0; } - final Completable.Int value = Completable.createInt(); - boolean hadRemoteException = false; - try { - mIInputContext.getCursorCapsMode(reqModes, ResultCallbacks.of(value)); - } catch (RemoteException e) { - hadRemoteException = true; - } - final int result = hadRemoteException ? 0 : Completable.getResultOrZero( + final Completable.Int value = mInvoker.getCursorCapsMode(reqModes); + final int result = Completable.getResultOrZero( value, TAG, "getCursorCapsMode()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); final AbstractInputMethodService inputMethodService = mInputMethodService.get(); @@ -245,14 +217,8 @@ public class InputConnectionWrapper implements InputConnection { return null; } - final Completable.ExtractedText value = Completable.createExtractedText(); - boolean hadRemoteException = false; - try { - mIInputContext.getExtractedText(request, flags, ResultCallbacks.of(value)); - } catch (RemoteException e) { - hadRemoteException = true; - } - final ExtractedText result = hadRemoteException ? null : Completable.getResultOrNull( + final Completable.ExtractedText value = mInvoker.getExtractedText(request, flags); + final ExtractedText result = Completable.getResultOrNull( value, TAG, "getExtractedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); final AbstractInputMethodService inputMethodService = mInputMethodService.get(); @@ -268,13 +234,11 @@ public class InputConnectionWrapper implements InputConnection { @AnyThread public boolean commitText(CharSequence text, int newCursorPosition) { - try { - mIInputContext.commitText(text, newCursorPosition); + final boolean handled = mInvoker.commitText(text, newCursorPosition); + if (handled) { notifyUserActionIfNecessary(); - return true; - } catch (RemoteException e) { - return false; } + return handled; } @AnyThread @@ -293,52 +257,27 @@ public class InputConnectionWrapper implements InputConnection { // This method is not implemented. return false; } - try { - mIInputContext.commitCompletion(text); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.commitCompletion(text); } @AnyThread public boolean commitCorrection(CorrectionInfo correctionInfo) { - try { - mIInputContext.commitCorrection(correctionInfo); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.commitCorrection(correctionInfo); } @AnyThread public boolean setSelection(int start, int end) { - try { - mIInputContext.setSelection(start, end); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.setSelection(start, end); } @AnyThread public boolean performEditorAction(int actionCode) { - try { - mIInputContext.performEditorAction(actionCode); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.performEditorAction(actionCode); } @AnyThread public boolean performContextMenuAction(int id) { - try { - mIInputContext.performContextMenuAction(id); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.performContextMenuAction(id); } @AnyThread @@ -347,84 +286,50 @@ public class InputConnectionWrapper implements InputConnection { // This method is not implemented. return false; } - try { - mIInputContext.setComposingRegion(start, end); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.setComposingRegion(start, end); } @AnyThread public boolean setComposingText(CharSequence text, int newCursorPosition) { - try { - mIInputContext.setComposingText(text, newCursorPosition); + final boolean handled = mInvoker.setComposingText(text, newCursorPosition); + if (handled) { notifyUserActionIfNecessary(); - return true; - } catch (RemoteException e) { - return false; } + return handled; } @AnyThread public boolean finishComposingText() { - try { - mIInputContext.finishComposingText(); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.finishComposingText(); } @AnyThread public boolean beginBatchEdit() { - try { - mIInputContext.beginBatchEdit(); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.beginBatchEdit(); } @AnyThread public boolean endBatchEdit() { - try { - mIInputContext.endBatchEdit(); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.endBatchEdit(); } @AnyThread public boolean sendKeyEvent(KeyEvent event) { - try { - mIInputContext.sendKeyEvent(event); + final boolean handled = mInvoker.sendKeyEvent(event); + if (handled) { notifyUserActionIfNecessary(); - return true; - } catch (RemoteException e) { - return false; } + return handled; } @AnyThread public boolean clearMetaKeyStates(int states) { - try { - mIInputContext.clearMetaKeyStates(states); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.clearMetaKeyStates(states); } @AnyThread public boolean deleteSurroundingText(int beforeLength, int afterLength) { - try { - mIInputContext.deleteSurroundingText(beforeLength, afterLength); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.deleteSurroundingText(beforeLength, afterLength); } @AnyThread @@ -433,12 +338,7 @@ public class InputConnectionWrapper implements InputConnection { // This method is not implemented. return false; } - try { - mIInputContext.deleteSurroundingTextInCodePoints(beforeLength, afterLength); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.deleteSurroundingTextInCodePoints(beforeLength, afterLength); } @AnyThread @@ -448,24 +348,13 @@ public class InputConnectionWrapper implements InputConnection { } @AnyThread - @Override public boolean performSpellCheck() { - try { - mIInputContext.performSpellCheck(); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.performSpellCheck(); } @AnyThread public boolean performPrivateCommand(String action, Bundle data) { - try { - mIInputContext.performPrivateCommand(action, data); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.performPrivateCommand(action, data); } @AnyThread @@ -478,13 +367,7 @@ public class InputConnectionWrapper implements InputConnection { // This method is not implemented. return false; } - final Completable.Int value = Completable.createInt(); - try { - mIInputContext.requestUpdateCursorAnchorInfo(cursorUpdateMode, - ResultCallbacks.of(value)); - } catch (RemoteException e) { - return false; - } + final Completable.Int value = mInvoker.requestUpdateCursorAnchorInfo(cursorUpdateMode); return Completable.getResultOrZero(value, TAG, "requestUpdateCursorAnchorInfo()", mCancellationGroup, MAX_WAIT_TIME_MILLIS) != 0; } @@ -520,12 +403,7 @@ public class InputConnectionWrapper implements InputConnection { inputMethodService.exposeContent(inputContentInfo, this); } - final Completable.Int value = Completable.createInt(); - try { - mIInputContext.commitContent(inputContentInfo, flags, opts, ResultCallbacks.of(value)); - } catch (RemoteException e) { - return false; - } + final Completable.Int value = mInvoker.commitContent(inputContentInfo, flags, opts); return Completable.getResultOrZero( value, TAG, "commitContent()", mCancellationGroup, MAX_WAIT_TIME_MILLIS) != 0; } @@ -535,12 +413,7 @@ public class InputConnectionWrapper implements InputConnection { */ @AnyThread public boolean setImeConsumesInput(boolean imeConsumesInput) { - try { - mIInputContext.setImeConsumesInput(imeConsumesInput); - return true; - } catch (RemoteException e) { - return false; - } + return mInvoker.setImeConsumesInput(imeConsumesInput); } @AnyThread