Implement InputConnection task cancellation
This CL introduces the task cancellation mechanism into RemoteInputConnection and RemoteInputConnectionImpl. The code idea is to ignore InputConnection tasks if the session IDs do not match. By incrementing the session ID upon every "interruption", we can effectively cancel any pending events issued before the "interruption" happened. Note that even with this CL RemoteInputConnection and RemoteInputConnectionImpl still uses "0" as the session ID. Hence there should be no user observable behavior change yet. Fix: 203086369 Test: presubmit Change-Id: I383c3958d2ac1a8d217706509fa12a92b381bbb3
This commit is contained in:
@@ -59,7 +59,8 @@ public final class IInputContextInvoker {
|
||||
|
||||
@NonNull
|
||||
InputConnectionCommandHeader createHeader() {
|
||||
return new InputConnectionCommandHeader();
|
||||
// TODO(b/203086369): Propagate session ID for interruption
|
||||
return new InputConnectionCommandHeader(0 /* sessionId */);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,19 @@ import android.os.Parcelable;
|
||||
* {@link android.inputmethodservice.RemoteInputConnection}.
|
||||
*/
|
||||
public final class InputConnectionCommandHeader implements Parcelable {
|
||||
public InputConnectionCommandHeader() {
|
||||
/**
|
||||
* An identifier that is to be used when multiplexing multiple sessions into a single
|
||||
* {@link com.android.internal.view.IInputContext}.
|
||||
*
|
||||
* <p>This ID is considered to belong to an implicit namespace defined for each
|
||||
* {@link com.android.internal.view.IInputContext} instance. Uniqueness of the session ID
|
||||
* across multiple instances of {@link com.android.internal.view.IInputContext} is not
|
||||
* guaranteed unless explicitly noted in a higher layer.</p>
|
||||
*/
|
||||
public final int mSessionId;
|
||||
|
||||
public InputConnectionCommandHeader(int sessionId) {
|
||||
mSessionId = sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,7 +50,8 @@ public final class InputConnectionCommandHeader implements Parcelable {
|
||||
new Parcelable.Creator<InputConnectionCommandHeader>() {
|
||||
@NonNull
|
||||
public InputConnectionCommandHeader createFromParcel(Parcel in) {
|
||||
return new InputConnectionCommandHeader();
|
||||
final int sessionId = in.readInt();
|
||||
return new InputConnectionCommandHeader(sessionId);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -49,5 +62,6 @@ public final class InputConnectionCommandHeader implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(mSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import static com.android.internal.inputmethod.InputConnectionProtoDumper.buildG
|
||||
import static com.android.internal.inputmethod.InputConnectionProtoDumper.buildGetTextAfterCursorProto;
|
||||
import static com.android.internal.inputmethod.InputConnectionProtoDumper.buildGetTextBeforeCursorProto;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Bundle;
|
||||
@@ -45,7 +47,9 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
import com.android.internal.view.IInputContext;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -62,6 +66,11 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
private static final String TAG = "RemoteInputConnectionImpl";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
@Retention(SOURCE)
|
||||
private @interface Dispatching {
|
||||
boolean cancellable();
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private InputConnection mInputConnection;
|
||||
@@ -77,6 +86,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
private final InputMethodManager mParentInputMethodManager;
|
||||
private final WeakReference<View> mServedView;
|
||||
|
||||
// TODO(b/203086369): This is to be used when interruption is implemented.
|
||||
private final AtomicInteger mCurrentSessionId = new AtomicInteger(0);
|
||||
|
||||
public RemoteInputConnectionImpl(@NonNull Looper looper,
|
||||
@NonNull InputConnection inputConnection,
|
||||
@NonNull InputMethodManager inputMethodManager, @Nullable View servedView) {
|
||||
@@ -120,6 +132,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
*
|
||||
* <p>Multiple invocations will be simply ignored.</p>
|
||||
*/
|
||||
@Dispatching(cancellable = false)
|
||||
public void deactivate() {
|
||||
if (isFinished()) {
|
||||
// This is a small performance optimization. Still only the 1st call of
|
||||
@@ -214,6 +227,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
* @param enabled the parameter to be passed to
|
||||
* {@link InputConnection#reportFullscreenMode(boolean)}.
|
||||
*/
|
||||
@Dispatching(cancellable = false)
|
||||
public void dispatchReportFullscreenMode(boolean enabled) {
|
||||
dispatch(() -> {
|
||||
final InputConnection ic = getInputConnection();
|
||||
@@ -224,10 +238,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void getTextAfterCursor(InputConnectionCommandHeader header, int length, int flags,
|
||||
AndroidFuture future /* T=CharSequence */) {
|
||||
dispatchWithTracing("getTextAfterCursor", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return null; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
|
||||
@@ -242,10 +260,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}, useImeTracing() ? result -> buildGetTextAfterCursorProto(length, flags, result) : null);
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void getTextBeforeCursor(InputConnectionCommandHeader header, int length, int flags,
|
||||
AndroidFuture future /* T=CharSequence */) {
|
||||
dispatchWithTracing("getTextBeforeCursor", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return null; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
|
||||
@@ -260,10 +282,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}, useImeTracing() ? result -> buildGetTextBeforeCursorProto(length, flags, result) : null);
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void getSelectedText(InputConnectionCommandHeader header, int flags,
|
||||
AndroidFuture future /* T=CharSequence */) {
|
||||
dispatchWithTracing("getSelectedText", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return null; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "getSelectedText on inactive InputConnection");
|
||||
@@ -278,10 +304,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}, useImeTracing() ? result -> buildGetSelectedTextProto(flags, result) : null);
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void getSurroundingText(InputConnectionCommandHeader header, int beforeLength,
|
||||
int afterLength, int flags, AndroidFuture future /* T=SurroundingText */) {
|
||||
dispatchWithTracing("getSurroundingText", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return null; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "getSurroundingText on inactive InputConnection");
|
||||
@@ -302,10 +332,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
beforeLength, afterLength, flags, result) : null);
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void getCursorCapsMode(InputConnectionCommandHeader header, int reqModes,
|
||||
AndroidFuture future /* T=Integer */) {
|
||||
dispatchWithTracing("getCursorCapsMode", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return 0; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
|
||||
@@ -315,10 +349,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}, useImeTracing() ? result -> buildGetCursorCapsModeProto(reqModes, result) : null);
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void getExtractedText(InputConnectionCommandHeader header, ExtractedTextRequest request,
|
||||
int flags, AndroidFuture future /* T=ExtractedText */) {
|
||||
dispatchWithTracing("getExtractedText", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return null; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "getExtractedText on inactive InputConnection");
|
||||
@@ -328,10 +366,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}, useImeTracing() ? result -> buildGetExtractedTextProto(request, flags, result) : null);
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void commitText(InputConnectionCommandHeader header, CharSequence text,
|
||||
int newCursorPosition) {
|
||||
dispatchWithTracing("commitText", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "commitText on inactive InputConnection");
|
||||
@@ -341,9 +383,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void commitCompletion(InputConnectionCommandHeader header, CompletionInfo text) {
|
||||
dispatchWithTracing("commitCompletion", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "commitCompletion on inactive InputConnection");
|
||||
@@ -353,9 +399,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void commitCorrection(InputConnectionCommandHeader header, CorrectionInfo info) {
|
||||
dispatchWithTracing("commitCorrection", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "commitCorrection on inactive InputConnection");
|
||||
@@ -369,9 +419,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void setSelection(InputConnectionCommandHeader header, int start, int end) {
|
||||
dispatchWithTracing("setSelection", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "setSelection on inactive InputConnection");
|
||||
@@ -381,9 +435,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void performEditorAction(InputConnectionCommandHeader header, int id) {
|
||||
dispatchWithTracing("performEditorAction", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "performEditorAction on inactive InputConnection");
|
||||
@@ -393,9 +451,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void performContextMenuAction(InputConnectionCommandHeader header, int id) {
|
||||
dispatchWithTracing("performContextMenuAction", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "performContextMenuAction on inactive InputConnection");
|
||||
@@ -405,9 +467,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void setComposingRegion(InputConnectionCommandHeader header, int start, int end) {
|
||||
dispatchWithTracing("setComposingRegion", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "setComposingRegion on inactive InputConnection");
|
||||
@@ -421,10 +487,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void setComposingText(InputConnectionCommandHeader header, CharSequence text,
|
||||
int newCursorPosition) {
|
||||
dispatchWithTracing("setComposingText", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "setComposingText on inactive InputConnection");
|
||||
@@ -439,7 +509,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
*
|
||||
* <p>This method is intended to be called only from {@link InputMethodManager}.</p>
|
||||
*/
|
||||
@Dispatching(cancellable = true)
|
||||
public void finishComposingTextFromImm() {
|
||||
final int currentSessionId = mCurrentSessionId.get();
|
||||
dispatchWithTracing("finishComposingTextFromImm", () -> {
|
||||
if (isFinished()) {
|
||||
// In this case, #finishComposingText() is guaranteed to be called already.
|
||||
@@ -449,6 +521,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (currentSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
// Note we do NOT check isActive() here, because this is safe
|
||||
// for an IME to call at any time, and we need to allow it
|
||||
@@ -462,6 +537,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void finishComposingText(InputConnectionCommandHeader header) {
|
||||
dispatchWithTracing("finishComposingText", () -> {
|
||||
@@ -473,6 +549,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
// Note we do NOT check isActive() here, because this is safe
|
||||
// for an IME to call at any time, and we need to allow it
|
||||
@@ -486,9 +565,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void sendKeyEvent(InputConnectionCommandHeader header, KeyEvent event) {
|
||||
dispatchWithTracing("sendKeyEvent", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "sendKeyEvent on inactive InputConnection");
|
||||
@@ -498,9 +581,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void clearMetaKeyStates(InputConnectionCommandHeader header, int states) {
|
||||
dispatchWithTracing("clearMetaKeyStates", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
|
||||
@@ -510,10 +597,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void deleteSurroundingText(InputConnectionCommandHeader header, int beforeLength,
|
||||
int afterLength) {
|
||||
dispatchWithTracing("deleteSurroundingText", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
|
||||
@@ -523,10 +614,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void deleteSurroundingTextInCodePoints(InputConnectionCommandHeader header,
|
||||
int beforeLength, int afterLength) {
|
||||
dispatchWithTracing("deleteSurroundingTextInCodePoints", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
|
||||
@@ -540,9 +635,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void beginBatchEdit(InputConnectionCommandHeader header) {
|
||||
dispatchWithTracing("beginBatchEdit", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "beginBatchEdit on inactive InputConnection");
|
||||
@@ -552,9 +651,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void endBatchEdit(InputConnectionCommandHeader header) {
|
||||
dispatchWithTracing("endBatchEdit", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "endBatchEdit on inactive InputConnection");
|
||||
@@ -564,9 +667,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void performSpellCheck(InputConnectionCommandHeader header) {
|
||||
dispatchWithTracing("performSpellCheck", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "performSpellCheck on inactive InputConnection");
|
||||
@@ -576,10 +683,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void performPrivateCommand(InputConnectionCommandHeader header, String action,
|
||||
Bundle data) {
|
||||
dispatchWithTracing("performPrivateCommand", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "performPrivateCommand on inactive InputConnection");
|
||||
@@ -589,10 +700,14 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void requestCursorUpdates(InputConnectionCommandHeader header, int cursorUpdateMode,
|
||||
int imeDisplayId, AndroidFuture future /* T=Boolean */) {
|
||||
dispatchWithTracing("requestCursorUpdates", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return false; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
|
||||
@@ -611,11 +726,15 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void commitContent(InputConnectionCommandHeader header,
|
||||
InputContentInfo inputContentInfo, int flags, Bundle opts,
|
||||
AndroidFuture future /* T=Boolean */) {
|
||||
dispatchWithTracing("commitContent", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return false; // cancelled
|
||||
}
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "commitContent on inactive InputConnection");
|
||||
@@ -634,9 +753,13 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
});
|
||||
}
|
||||
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void setImeConsumesInput(InputConnectionCommandHeader header, boolean imeConsumesInput) {
|
||||
dispatchWithTracing("setImeConsumesInput", () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "setImeConsumesInput on inactive InputConnection");
|
||||
|
||||
Reference in New Issue
Block a user