Merge "Use AndroidFuture instead"
This commit is contained in:
committed by
Android (Google) Code Review
commit
6da601d5dd
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.NonNull;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.IntSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Defines a set of helper methods to callback corresponding results in {@link ResultCallbacks}.
|
||||
*/
|
||||
public final class CallbackUtils {
|
||||
|
||||
/**
|
||||
* Not intended to be instantiated.
|
||||
*/
|
||||
private CallbackUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method using given {@link IBooleanResultCallback} to callback the result.
|
||||
*
|
||||
* @param callback {@link IBooleanResultCallback} to be called back.
|
||||
* @param resultSupplier the supplier from which the result is provided.
|
||||
*/
|
||||
public static void onResult(@NonNull IBooleanResultCallback callback,
|
||||
@NonNull BooleanSupplier resultSupplier) {
|
||||
boolean result = false;
|
||||
Throwable exception = null;
|
||||
|
||||
try {
|
||||
result = resultSupplier.getAsBoolean();
|
||||
} catch (Throwable throwable) {
|
||||
exception = throwable;
|
||||
}
|
||||
|
||||
try {
|
||||
if (exception != null) {
|
||||
callback.onError(ThrowableHolder.of(exception));
|
||||
return;
|
||||
}
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException ignored) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method using given {@link IIntResultCallback} to callback the result.
|
||||
*
|
||||
* @param callback {@link IIntResultCallback} to be called back.
|
||||
* @param resultSupplier the supplier from which the result is provided.
|
||||
*/
|
||||
public static void onResult(@NonNull IIntResultCallback callback,
|
||||
@NonNull IntSupplier resultSupplier) {
|
||||
int result = 0;
|
||||
Throwable exception = null;
|
||||
|
||||
try {
|
||||
result = resultSupplier.getAsInt();
|
||||
} catch (Throwable throwable) {
|
||||
exception = throwable;
|
||||
}
|
||||
|
||||
try {
|
||||
if (exception != null) {
|
||||
callback.onError(ThrowableHolder.of(exception));
|
||||
return;
|
||||
}
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException ignored) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method using given {@link IVoidResultCallback} to callback the result.
|
||||
*
|
||||
* @param callback {@link IVoidResultCallback} to be called back.
|
||||
* @param runnable to execute the given method
|
||||
*/
|
||||
public static void onResult(@NonNull IVoidResultCallback callback,
|
||||
@NonNull Runnable runnable) {
|
||||
Throwable exception = null;
|
||||
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable throwable) {
|
||||
exception = throwable;
|
||||
}
|
||||
|
||||
try {
|
||||
if (exception != null) {
|
||||
callback.onError(ThrowableHolder.of(exception));
|
||||
return;
|
||||
}
|
||||
callback.onResult();
|
||||
} catch (RemoteException ignored) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method using given {@link IInputContentUriTokenResultCallback} to callback the
|
||||
* result.
|
||||
*
|
||||
* @param callback {@link IInputContentUriTokenResultCallback} to be called back.
|
||||
* @param resultSupplier the supplier from which the result is provided.
|
||||
*/
|
||||
public static void onResult(@NonNull IInputContentUriTokenResultCallback callback,
|
||||
@NonNull Supplier<IInputContentUriToken> resultSupplier) {
|
||||
IInputContentUriToken result = null;
|
||||
Throwable exception = null;
|
||||
|
||||
try {
|
||||
result = resultSupplier.get();
|
||||
} catch (Throwable throwable) {
|
||||
exception = throwable;
|
||||
}
|
||||
|
||||
try {
|
||||
if (exception != null) {
|
||||
callback.onError(ThrowableHolder.of(exception));
|
||||
return;
|
||||
}
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException ignored) { }
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 com.android.internal.inputmethod.ThrowableHolder;
|
||||
|
||||
oneway interface IBooleanResultCallback {
|
||||
void onResult(boolean result);
|
||||
void onError(in ThrowableHolder exception);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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;
|
||||
|
||||
oneway interface ICharSequenceResultCallback {
|
||||
void onResult(in CharSequence result);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.view.inputmethod.ExtractedText;
|
||||
|
||||
oneway interface IExtractedTextResultCallback {
|
||||
void onResult(in ExtractedText result);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 com.android.internal.inputmethod.IInputContentUriToken;
|
||||
import com.android.internal.inputmethod.ThrowableHolder;
|
||||
|
||||
oneway interface IInputContentUriTokenResultCallback {
|
||||
void onResult(in IInputContentUriToken result);
|
||||
void onError(in ThrowableHolder exception);
|
||||
}
|
||||
@@ -28,14 +28,14 @@ import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputContentInfo;
|
||||
import android.view.inputmethod.SurroundingText;
|
||||
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
import com.android.internal.view.IInputContext;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* A stateless wrapper of {@link com.android.internal.view.IInputContext} to encapsulate boilerplate
|
||||
* code around {@link CompletableFuture} and {@link RemoteException}.
|
||||
* code around {@link AndroidFuture} and {@link RemoteException}.
|
||||
*/
|
||||
public final class IInputContextInvoker {
|
||||
|
||||
@@ -63,19 +63,19 @@ public final class IInputContextInvoker {
|
||||
*
|
||||
* @param length {@code length} parameter to be passed.
|
||||
* @param flags {@code flags} parameter to be passed.
|
||||
* @return {@link CompletableFuture<CharSequence>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<CharSequence>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<CharSequence> getTextAfterCursor(int length, int flags) {
|
||||
final CompletableFuture<CharSequence> value = new CompletableFuture<>();
|
||||
public AndroidFuture<CharSequence> getTextAfterCursor(int length, int flags) {
|
||||
final AndroidFuture<CharSequence> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.getTextAfterCursor(length, flags, ResultCallbacks.ofCharSequence(value));
|
||||
mIInputContext.getTextAfterCursor(length, flags, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,39 +83,38 @@ public final class IInputContextInvoker {
|
||||
*
|
||||
* @param length {@code length} parameter to be passed.
|
||||
* @param flags {@code flags} parameter to be passed.
|
||||
* @return {@link CompletableFuture<CharSequence>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<CharSequence>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<CharSequence> getTextBeforeCursor(int length, int flags) {
|
||||
final CompletableFuture<CharSequence> value = new CompletableFuture<>();
|
||||
public AndroidFuture<CharSequence> getTextBeforeCursor(int length, int flags) {
|
||||
final AndroidFuture<CharSequence> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.getTextBeforeCursor(length, flags,
|
||||
ResultCallbacks.ofCharSequence(value));
|
||||
mIInputContext.getTextBeforeCursor(length, flags, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes {@link IInputContext#getSelectedText(int, ICharSequenceResultCallback)}.
|
||||
*
|
||||
* @param flags {@code flags} parameter to be passed.
|
||||
* @return {@link CompletableFuture<CharSequence>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<CharSequence>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<CharSequence> getSelectedText(int flags) {
|
||||
final CompletableFuture<CharSequence> value = new CompletableFuture<>();
|
||||
public AndroidFuture<CharSequence> getSelectedText(int flags) {
|
||||
final AndroidFuture<CharSequence> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.getSelectedText(flags, ResultCallbacks.ofCharSequence(value));
|
||||
mIInputContext.getSelectedText(flags, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,40 +124,39 @@ public final class IInputContextInvoker {
|
||||
* @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 CompletableFuture<SurroundingText>} that can be used to retrieve the
|
||||
* @return {@link AndroidFuture<SurroundingText>} that can be used to retrieve the
|
||||
* invocation result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<SurroundingText> getSurroundingText(int beforeLength, int afterLength,
|
||||
public AndroidFuture<SurroundingText> getSurroundingText(int beforeLength, int afterLength,
|
||||
int flags) {
|
||||
final CompletableFuture<SurroundingText> value = new CompletableFuture<>();
|
||||
final AndroidFuture<SurroundingText> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.getSurroundingText(beforeLength, afterLength, flags,
|
||||
ResultCallbacks.ofSurroundingText(value));
|
||||
mIInputContext.getSurroundingText(beforeLength, afterLength, flags, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes {@link IInputContext#getCursorCapsMode(int, IIntResultCallback)}.
|
||||
*
|
||||
* @param reqModes {@code reqModes} parameter to be passed.
|
||||
* @return {@link CompletableFuture<Integer>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<Integer>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<Integer> getCursorCapsMode(int reqModes) {
|
||||
final CompletableFuture<Integer> value = new CompletableFuture<>();
|
||||
public AndroidFuture<Integer> getCursorCapsMode(int reqModes) {
|
||||
final AndroidFuture<Integer> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.getCursorCapsMode(reqModes, ResultCallbacks.ofInteger(value));
|
||||
mIInputContext.getCursorCapsMode(reqModes, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,20 +165,20 @@ public final class IInputContextInvoker {
|
||||
*
|
||||
* @param request {@code request} parameter to be passed.
|
||||
* @param flags {@code flags} parameter to be passed.
|
||||
* @return {@link CompletableFuture<ExtractedText>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<ExtractedText>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<ExtractedText> getExtractedText(ExtractedTextRequest request,
|
||||
public AndroidFuture<ExtractedText> getExtractedText(ExtractedTextRequest request,
|
||||
int flags) {
|
||||
final CompletableFuture<ExtractedText> value = new CompletableFuture<>();
|
||||
final AndroidFuture<ExtractedText> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.getExtractedText(request, flags, ResultCallbacks.ofExtractedText(value));
|
||||
mIInputContext.getExtractedText(request, flags, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -479,19 +477,19 @@ public final class IInputContextInvoker {
|
||||
* Invokes {@link IInputContext#requestCursorUpdates(int, IIntResultCallback)}.
|
||||
*
|
||||
* @param cursorUpdateMode {@code cursorUpdateMode} parameter to be passed.
|
||||
* @return {@link CompletableFuture<Boolean>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<Boolean>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<Boolean> requestCursorUpdates(int cursorUpdateMode) {
|
||||
final CompletableFuture<Boolean> value = new CompletableFuture<>();
|
||||
public AndroidFuture<Boolean> requestCursorUpdates(int cursorUpdateMode) {
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.requestCursorUpdates(cursorUpdateMode, ResultCallbacks.ofBoolean(value));
|
||||
mIInputContext.requestCursorUpdates(cursorUpdateMode, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,21 +499,20 @@ public final class IInputContextInvoker {
|
||||
* @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 CompletableFuture<Boolean>} that can be used to retrieve the invocation
|
||||
* @return {@link AndroidFuture<Boolean>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public CompletableFuture<Boolean> commitContent(InputContentInfo inputContentInfo, int flags,
|
||||
public AndroidFuture<Boolean> commitContent(InputContentInfo inputContentInfo, int flags,
|
||||
Bundle opts) {
|
||||
final CompletableFuture<Boolean> value = new CompletableFuture<>();
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.commitContent(inputContentInfo, flags, opts,
|
||||
ResultCallbacks.ofBoolean(value));
|
||||
mIInputContext.commitContent(inputContentInfo, flags, opts, future);
|
||||
} catch (RemoteException e) {
|
||||
value.completeExceptionally(e);
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return value;
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,10 +19,7 @@ package com.android.internal.inputmethod;
|
||||
import android.net.Uri;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.internal.inputmethod.IBooleanResultCallback;
|
||||
import com.android.internal.inputmethod.IInputContentUriToken;
|
||||
import com.android.internal.inputmethod.IInputContentUriTokenResultCallback;
|
||||
import com.android.internal.inputmethod.IVoidResultCallback;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
|
||||
/**
|
||||
* Defines priviledged operations that only the current IME is allowed to call.
|
||||
@@ -32,17 +29,17 @@ oneway interface IInputMethodPrivilegedOperations {
|
||||
void setImeWindowStatusAsync(int vis, int backDisposition);
|
||||
void reportStartInputAsync(in IBinder startInputToken);
|
||||
void createInputContentUriToken(in Uri contentUri, in String packageName,
|
||||
in IInputContentUriTokenResultCallback resultCallback);
|
||||
in AndroidFuture future /* T=IBinder */);
|
||||
void reportFullscreenModeAsync(boolean fullscreen);
|
||||
void setInputMethod(String id, in IVoidResultCallback resultCallback);
|
||||
void setInputMethod(String id, in AndroidFuture future /* T=Void */);
|
||||
void setInputMethodAndSubtype(String id, in InputMethodSubtype subtype,
|
||||
in IVoidResultCallback resultCallback);
|
||||
void hideMySoftInput(int flags, in IVoidResultCallback resultCallback);
|
||||
void showMySoftInput(int flags, in IVoidResultCallback resultCallback);
|
||||
in AndroidFuture future /* T=Void */);
|
||||
void hideMySoftInput(int flags, in AndroidFuture future /* T=Void */);
|
||||
void showMySoftInput(int flags, in AndroidFuture future /* T=Void */);
|
||||
void updateStatusIconAsync(String packageName, int iconId);
|
||||
void switchToPreviousInputMethod(in IBooleanResultCallback resultCallback);
|
||||
void switchToNextInputMethod(boolean onlyCurrentIme, in IBooleanResultCallback resultCallback);
|
||||
void shouldOfferSwitchingToNextInputMethod(in IBooleanResultCallback resultCallback);
|
||||
void switchToPreviousInputMethod(in AndroidFuture future /* T=Boolean */);
|
||||
void switchToNextInputMethod(boolean onlyCurrentIme, in AndroidFuture future /* T=Boolean */);
|
||||
void shouldOfferSwitchingToNextInputMethod(in AndroidFuture future /* T=Boolean */);
|
||||
void notifyUserActionAsync();
|
||||
void applyImeVisibilityAsync(IBinder showOrHideInputToken, boolean setVisible);
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.view.inputmethod.SurroundingText;
|
||||
|
||||
oneway interface ISurroundingTextResultCallback {
|
||||
void onResult(in SurroundingText result);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 com.android.internal.inputmethod.ThrowableHolder;
|
||||
|
||||
oneway interface IVoidResultCallback {
|
||||
void onResult();
|
||||
void onError(in ThrowableHolder exception);
|
||||
}
|
||||
@@ -28,9 +28,9 @@ import android.view.View;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* A utility class to take care of boilerplate code around IPCs.
|
||||
@@ -143,7 +143,7 @@ public final class InputMethodPrivilegedOperations {
|
||||
|
||||
/**
|
||||
* Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String,
|
||||
* IInputContentUriTokenResultCallback)}.
|
||||
* AndroidFuture)}.
|
||||
*
|
||||
* @param contentUri Content URI to which a temporary read permission should be granted
|
||||
* @param packageName Indicates what package needs to have a temporary read permission
|
||||
@@ -157,10 +157,9 @@ public final class InputMethodPrivilegedOperations {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<IInputContentUriToken> value = new CompletableFuture<>();
|
||||
ops.createInputContentUriToken(contentUri, packageName,
|
||||
ResultCallbacks.ofIInputContentUriToken(value));
|
||||
return CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<IBinder> future = new AndroidFuture<>();
|
||||
ops.createInputContentUriToken(contentUri, packageName, future);
|
||||
return IInputContentUriToken.Stub.asInterface(CompletableFutureUtil.getResult(future));
|
||||
} catch (RemoteException e) {
|
||||
// For historical reasons, this error was silently ignored.
|
||||
// Note that the caller already logs error so we do not need additional Log.e() here.
|
||||
@@ -207,7 +206,7 @@ public final class InputMethodPrivilegedOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link IInputMethodPrivilegedOperations#setInputMethod(String, IVoidResultCallback)}.
|
||||
* Calls {@link IInputMethodPrivilegedOperations#setInputMethod(String, AndroidFuture)}.
|
||||
*
|
||||
* @param id IME ID of the IME to switch to
|
||||
* @see android.view.inputmethod.InputMethodInfo#getId()
|
||||
@@ -219,9 +218,9 @@ public final class InputMethodPrivilegedOperations {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Void> value = new CompletableFuture<>();
|
||||
ops.setInputMethod(id, ResultCallbacks.ofVoid(value));
|
||||
CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<Void> future = new AndroidFuture<>();
|
||||
ops.setInputMethod(id, future);
|
||||
CompletableFutureUtil.getResult(future);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -229,7 +228,7 @@ public final class InputMethodPrivilegedOperations {
|
||||
|
||||
/**
|
||||
* Calls {@link IInputMethodPrivilegedOperations#setInputMethodAndSubtype(String,
|
||||
* InputMethodSubtype, IVoidResultCallback)}
|
||||
* InputMethodSubtype, AndroidFuture)}
|
||||
*
|
||||
* @param id IME ID of the IME to switch to
|
||||
* @param subtype {@link InputMethodSubtype} to switch to
|
||||
@@ -242,9 +241,9 @@ public final class InputMethodPrivilegedOperations {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Void> value = new CompletableFuture<>();
|
||||
ops.setInputMethodAndSubtype(id, subtype, ResultCallbacks.ofVoid(value));
|
||||
CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<Void> future = new AndroidFuture<>();
|
||||
ops.setInputMethodAndSubtype(id, subtype, future);
|
||||
CompletableFutureUtil.getResult(future);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -264,16 +263,16 @@ public final class InputMethodPrivilegedOperations {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Void> value = new CompletableFuture<>();
|
||||
ops.hideMySoftInput(flags, ResultCallbacks.ofVoid(value));
|
||||
CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<Void> future = new AndroidFuture<>();
|
||||
ops.hideMySoftInput(flags, future);
|
||||
CompletableFutureUtil.getResult(future);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link IInputMethodPrivilegedOperations#showMySoftInput(int, IVoidResultCallback)}
|
||||
* Calls {@link IInputMethodPrivilegedOperations#showMySoftInput(int, AndroidFuture)}
|
||||
*
|
||||
* @param flags additional operating flags
|
||||
* @see android.view.inputmethod.InputMethodManager#SHOW_IMPLICIT
|
||||
@@ -286,17 +285,16 @@ public final class InputMethodPrivilegedOperations {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Void> value = new CompletableFuture<>();
|
||||
ops.showMySoftInput(flags, ResultCallbacks.ofVoid(value));
|
||||
CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<Void> future = new AndroidFuture<>();
|
||||
ops.showMySoftInput(flags, future);
|
||||
CompletableFutureUtil.getResult(future);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link IInputMethodPrivilegedOperations#switchToPreviousInputMethod(
|
||||
* IBooleanResultCallback)}
|
||||
* Calls {@link IInputMethodPrivilegedOperations#switchToPreviousInputMethod(AndroidFuture)}
|
||||
*
|
||||
* @return {@code true} if handled
|
||||
*/
|
||||
@@ -307,8 +305,8 @@ public final class InputMethodPrivilegedOperations {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Boolean> value = new CompletableFuture<>();
|
||||
ops.switchToPreviousInputMethod(ResultCallbacks.ofBoolean(value));
|
||||
final AndroidFuture<Boolean> value = new AndroidFuture<>();
|
||||
ops.switchToPreviousInputMethod(value);
|
||||
return CompletableFutureUtil.getResult(value);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
@@ -330,9 +328,9 @@ public final class InputMethodPrivilegedOperations {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Boolean> value = new CompletableFuture<>();
|
||||
ops.switchToNextInputMethod(onlyCurrentIme, ResultCallbacks.ofBoolean(value));
|
||||
return CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
ops.switchToNextInputMethod(onlyCurrentIme, future);
|
||||
return CompletableFutureUtil.getResult(future);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -340,7 +338,7 @@ public final class InputMethodPrivilegedOperations {
|
||||
|
||||
/**
|
||||
* Calls {@link IInputMethodPrivilegedOperations#shouldOfferSwitchingToNextInputMethod(
|
||||
* IBooleanResultCallback)}
|
||||
* AndroidFuture)}
|
||||
*
|
||||
* @return {@code true} if the IEM should offer a way to globally switch IME
|
||||
*/
|
||||
@@ -351,9 +349,9 @@ public final class InputMethodPrivilegedOperations {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
final CompletableFuture<Boolean> value = new CompletableFuture<>();
|
||||
ops.shouldOfferSwitchingToNextInputMethod(ResultCallbacks.ofBoolean(value));
|
||||
return CompletableFutureUtil.getResult(value);
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
ops.shouldOfferSwitchingToNextInputMethod(future);
|
||||
return CompletableFutureUtil.getResult(future);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.annotation.Nullable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Trace;
|
||||
import android.util.Log;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
@@ -40,6 +39,7 @@ import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.inputmethod.SurroundingText;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
import com.android.internal.view.IInputContext;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -220,7 +220,10 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTextAfterCursor(int length, int flags, ICharSequenceResultCallback callback) {
|
||||
public void getTextAfterCursor(int length, int flags,
|
||||
AndroidFuture future /* T=CharSequence */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<CharSequence> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getTextAfterCursor");
|
||||
try {
|
||||
@@ -238,12 +241,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getTextAfterCursor", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to getTextAfterCursor()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -251,7 +249,10 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTextBeforeCursor(int length, int flags, ICharSequenceResultCallback callback) {
|
||||
public void getTextBeforeCursor(int length, int flags,
|
||||
AndroidFuture future /* T=CharSequence */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<CharSequence> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getTextBeforeCursor");
|
||||
try {
|
||||
@@ -269,12 +270,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getTextBeforeCursor", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to getTextBeforeCursor()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -282,7 +278,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSelectedText(int flags, ICharSequenceResultCallback callback) {
|
||||
public void getSelectedText(int flags, AndroidFuture future /* T=CharSequence */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<CharSequence> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getSelectedText");
|
||||
try {
|
||||
@@ -300,12 +298,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getSelectedText", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to getSelectedText()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -314,7 +307,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
|
||||
@Override
|
||||
public void getSurroundingText(int beforeLength, int afterLength, int flags,
|
||||
ISurroundingTextResultCallback callback) {
|
||||
AndroidFuture future /* T=SurroundingText */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<SurroundingText> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getSurroundingText");
|
||||
try {
|
||||
@@ -332,12 +327,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getSurroundingText", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to getSurroundingText()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -345,7 +335,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCursorCapsMode(int reqModes, IIntResultCallback callback) {
|
||||
public void getCursorCapsMode(int reqModes, AndroidFuture future /* T=Integer */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Integer> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getCursorCapsMode");
|
||||
try {
|
||||
@@ -363,12 +355,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getCursorCapsMode", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to getCursorCapsMode()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -377,7 +364,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
|
||||
@Override
|
||||
public void getExtractedText(ExtractedTextRequest request, int flags,
|
||||
IExtractedTextResultCallback callback) {
|
||||
AndroidFuture future /* T=ExtractedText */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<ExtractedText> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getExtractedText");
|
||||
try {
|
||||
@@ -395,12 +384,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getExtractedText", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to getExtractedText()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -710,7 +694,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestCursorUpdates(int cursorUpdateMode, IBooleanResultCallback callback) {
|
||||
public void requestCursorUpdates(int cursorUpdateMode, AndroidFuture future /* T=Boolean */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Boolean> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#requestCursorUpdates");
|
||||
try {
|
||||
@@ -722,12 +708,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.requestCursorUpdates(cursorUpdateMode);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to requestCursorUpdates()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
@@ -736,7 +717,9 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
|
||||
@Override
|
||||
public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
|
||||
IBooleanResultCallback callback) {
|
||||
AndroidFuture future /* T=Boolean */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Boolean> typedFuture = future;
|
||||
dispatch(() -> {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#commitContent");
|
||||
try {
|
||||
@@ -754,12 +737,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
result = ic.commitContent(inputContentInfo, flags, opts);
|
||||
}
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to return the result to commitContent()."
|
||||
+ " result=" + result, e);
|
||||
}
|
||||
typedFuture.complete(result);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_INPUT);
|
||||
}
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.BinderThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.SurroundingText;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Defines a set of factory methods to create {@link android.os.IBinder}-based callbacks that are
|
||||
* associated with completable objects defined in {@link CompletableFuture}.
|
||||
*/
|
||||
public final class ResultCallbacks {
|
||||
|
||||
/**
|
||||
* Not intended to be instantiated.
|
||||
*/
|
||||
private ResultCallbacks() {
|
||||
}
|
||||
|
||||
private static final class LightweightThrowable extends RuntimeException {
|
||||
LightweightThrowable(@Nullable ThrowableHolder throwableHolder) {
|
||||
super(throwableHolder != null ? throwableHolder.getMessage() : null,
|
||||
null, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@Nullable
|
||||
private static <T> T unwrap(@NonNull AtomicReference<T> atomicRef) {
|
||||
// Only the first caller will receive the non-null original object.
|
||||
return atomicRef.getAndSet(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link IIntResultCallback.Stub} that is to set {@link CompletableFuture<Integer>}
|
||||
* when receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<Integer>} to be set when receiving the result.
|
||||
* @return {@link IIntResultCallback.Stub} that can be passed as a binder IPC parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static IIntResultCallback.Stub ofInteger(@NonNull CompletableFuture<Integer> value) {
|
||||
final AtomicReference<CompletableFuture<Integer>> atomicRef = new AtomicReference<>(value);
|
||||
|
||||
return new IIntResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult(int result) {
|
||||
final CompletableFuture<Integer> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(result);
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onError(ThrowableHolder throwableHolder) {
|
||||
final CompletableFuture<Integer> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.completeExceptionally(new LightweightThrowable(throwableHolder));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link ICharSequenceResultCallback.Stub} that is to set
|
||||
* {@link CompletableFuture<CharSequence>} when receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<CharSequence>} to be set when receiving the result.
|
||||
* @return {@link ICharSequenceResultCallback.Stub} that can be passed as a binder IPC
|
||||
* parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static ICharSequenceResultCallback.Stub ofCharSequence(
|
||||
@NonNull CompletableFuture<CharSequence> value) {
|
||||
final AtomicReference<CompletableFuture<CharSequence>> atomicRef =
|
||||
new AtomicReference<>(value);
|
||||
|
||||
return new ICharSequenceResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult(CharSequence result) {
|
||||
final CompletableFuture<CharSequence> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link IExtractedTextResultCallback.Stub} that is to set
|
||||
* {@link CompletableFuture<ExtractedText>} when receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<ExtractedText>} to be set when receiving the result.
|
||||
* @return {@link IExtractedTextResultCallback.Stub} that can be passed as a binder IPC
|
||||
* parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static IExtractedTextResultCallback.Stub ofExtractedText(
|
||||
@NonNull CompletableFuture<ExtractedText> value) {
|
||||
final AtomicReference<CompletableFuture<ExtractedText>> atomicRef =
|
||||
new AtomicReference<>(value);
|
||||
|
||||
return new IExtractedTextResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult(android.view.inputmethod.ExtractedText result) {
|
||||
final CompletableFuture<ExtractedText> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link ISurroundingTextResultCallback.Stub} that is to set
|
||||
* {@link CompletableFuture<SurroundingText>} when receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<SurroundingText>} to be set when receiving the result.
|
||||
* @return {@link ISurroundingTextResultCallback.Stub} that can be passed as a binder IPC
|
||||
* parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static ISurroundingTextResultCallback.Stub ofSurroundingText(
|
||||
@NonNull CompletableFuture<SurroundingText> value) {
|
||||
final AtomicReference<CompletableFuture<SurroundingText>> atomicRef =
|
||||
new AtomicReference<>(value);
|
||||
|
||||
return new ISurroundingTextResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult(android.view.inputmethod.SurroundingText result) {
|
||||
final CompletableFuture<SurroundingText> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link IBooleanResultCallback.Stub} that is to set {@link CompletableFuture<Boolean>}
|
||||
* when receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<Boolean>} to be set when receiving the result.
|
||||
* @return {@link IBooleanResultCallback.Stub} that can be passed as a binder IPC parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static IBooleanResultCallback.Stub ofBoolean(@NonNull CompletableFuture<Boolean> value) {
|
||||
final AtomicReference<CompletableFuture<Boolean>> atomicRef = new AtomicReference<>(value);
|
||||
|
||||
return new IBooleanResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult(boolean result) {
|
||||
final CompletableFuture<Boolean> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(result);
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onError(ThrowableHolder throwableHolder) {
|
||||
final CompletableFuture<Boolean> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.completeExceptionally(new LightweightThrowable(throwableHolder));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link IVoidResultCallback.Stub} that is to set {@link CompletableFuture<Void>} when
|
||||
* receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<Void>} to be set when receiving the result.
|
||||
* @return {@link IVoidResultCallback.Stub} that can be passed as a binder IPC parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static IVoidResultCallback.Stub ofVoid(@NonNull CompletableFuture<Void> value) {
|
||||
final AtomicReference<CompletableFuture<Void>> atomicRef = new AtomicReference<>(value);
|
||||
|
||||
return new IVoidResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult() {
|
||||
final CompletableFuture<Void> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(null);
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onError(ThrowableHolder throwableHolder) {
|
||||
final CompletableFuture<Void> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.completeExceptionally(new LightweightThrowable(throwableHolder));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link IInputContentUriTokenResultCallback.Stub} that is to set
|
||||
* {@link CompletableFuture<IInputContentUriToken>} when receiving the result.
|
||||
*
|
||||
* @param value {@link CompletableFuture<IInputContentUriToken>} to be set when receiving the
|
||||
* result.
|
||||
* @return {@link IInputContentUriTokenResultCallback.Stub} that can be passed as a binder IPC
|
||||
* parameter.
|
||||
*/
|
||||
@AnyThread
|
||||
public static IInputContentUriTokenResultCallback.Stub ofIInputContentUriToken(
|
||||
@NonNull CompletableFuture<IInputContentUriToken> value) {
|
||||
final AtomicReference<CompletableFuture<IInputContentUriToken>>
|
||||
atomicRef = new AtomicReference<>(value);
|
||||
|
||||
return new IInputContentUriTokenResultCallback.Stub() {
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onResult(IInputContentUriToken result) {
|
||||
final CompletableFuture<IInputContentUriToken> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.complete(result);
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onError(ThrowableHolder throwableHolder) {
|
||||
final CompletableFuture<IInputContentUriToken> value = unwrap(atomicRef);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
value.completeExceptionally(new LightweightThrowable(throwableHolder));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -23,11 +23,7 @@ import android.view.inputmethod.CorrectionInfo;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputContentInfo;
|
||||
|
||||
import com.android.internal.inputmethod.IBooleanResultCallback;
|
||||
import com.android.internal.inputmethod.ICharSequenceResultCallback;
|
||||
import com.android.internal.inputmethod.IExtractedTextResultCallback;
|
||||
import com.android.internal.inputmethod.IIntResultCallback;
|
||||
import com.android.internal.inputmethod.ISurroundingTextResultCallback;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
|
||||
/**
|
||||
* Interface from an input method to the application, allowing it to perform
|
||||
@@ -35,14 +31,14 @@ import com.android.internal.inputmethod.ISurroundingTextResultCallback;
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IInputContext {
|
||||
void getTextBeforeCursor(int length, int flags, ICharSequenceResultCallback callback);
|
||||
void getTextBeforeCursor(int length, int flags, in AndroidFuture future /* T=CharSequence */);
|
||||
|
||||
void getTextAfterCursor(int length, int flags, ICharSequenceResultCallback callback);
|
||||
void getTextAfterCursor(int length, int flags, in AndroidFuture future /* T=CharSequence */);
|
||||
|
||||
void getCursorCapsMode(int reqModes, IIntResultCallback callback);
|
||||
void getCursorCapsMode(int reqModes, in AndroidFuture future /* T=Integer */);
|
||||
|
||||
void getExtractedText(in ExtractedTextRequest request, int flags,
|
||||
IExtractedTextResultCallback callback);
|
||||
in AndroidFuture future /* T=ExtractedText */);
|
||||
|
||||
void deleteSurroundingText(int beforeLength, int afterLength);
|
||||
void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength);
|
||||
@@ -50,7 +46,7 @@ import com.android.internal.inputmethod.ISurroundingTextResultCallback;
|
||||
void setComposingText(CharSequence text, int newCursorPosition);
|
||||
|
||||
void finishComposingText();
|
||||
|
||||
|
||||
void commitText(CharSequence text, int newCursorPosition);
|
||||
|
||||
void commitCompletion(in CompletionInfo completion);
|
||||
@@ -58,34 +54,34 @@ import com.android.internal.inputmethod.ISurroundingTextResultCallback;
|
||||
void commitCorrection(in CorrectionInfo correction);
|
||||
|
||||
void setSelection(int start, int end);
|
||||
|
||||
|
||||
void performEditorAction(int actionCode);
|
||||
|
||||
|
||||
void performContextMenuAction(int id);
|
||||
|
||||
|
||||
void beginBatchEdit();
|
||||
|
||||
|
||||
void endBatchEdit();
|
||||
|
||||
void sendKeyEvent(in KeyEvent event);
|
||||
|
||||
|
||||
void clearMetaKeyStates(int states);
|
||||
|
||||
|
||||
void performSpellCheck();
|
||||
|
||||
void performPrivateCommand(String action, in Bundle data);
|
||||
|
||||
void setComposingRegion(int start, int end);
|
||||
|
||||
void getSelectedText(int flags, ICharSequenceResultCallback callback);
|
||||
void getSelectedText(int flags, in AndroidFuture future /* T=CharSequence */);
|
||||
|
||||
void requestCursorUpdates(int cursorUpdateMode, IBooleanResultCallback callback);
|
||||
void requestCursorUpdates(int cursorUpdateMode, in AndroidFuture future /* T=Boolean */);
|
||||
|
||||
void commitContent(in InputContentInfo inputContentInfo, int flags, in Bundle opts,
|
||||
IBooleanResultCallback callback);
|
||||
in AndroidFuture future /* T=Boolean */);
|
||||
|
||||
void getSurroundingText(int beforeLength, int afterLength, int flags,
|
||||
ISurroundingTextResultCallback callback);
|
||||
in AndroidFuture future /* T=SurroundingText */);
|
||||
|
||||
void setImeConsumesInput(boolean imeConsumesInput);
|
||||
}
|
||||
|
||||
@@ -152,12 +152,9 @@ import android.view.inputmethod.InputMethodSubtype;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.compat.IPlatformCompat;
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.inputmethod.CallbackUtils;
|
||||
import com.android.internal.inputmethod.IBooleanResultCallback;
|
||||
import com.android.internal.infra.AndroidFuture;
|
||||
import com.android.internal.inputmethod.IInputContentUriToken;
|
||||
import com.android.internal.inputmethod.IInputContentUriTokenResultCallback;
|
||||
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
|
||||
import com.android.internal.inputmethod.IVoidResultCallback;
|
||||
import com.android.internal.inputmethod.ImeTracing;
|
||||
import com.android.internal.inputmethod.InputBindResult;
|
||||
import com.android.internal.inputmethod.InputMethodDebug;
|
||||
@@ -5842,9 +5839,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
@BinderThread
|
||||
@Override
|
||||
public void createInputContentUriToken(Uri contentUri, String packageName,
|
||||
IInputContentUriTokenResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback,
|
||||
() -> mImms.createInputContentUriToken(mToken, contentUri, packageName));
|
||||
AndroidFuture future /* T=IBinder */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<IBinder> typedFuture = future;
|
||||
try {
|
||||
typedFuture.complete(mImms.createInputContentUriToken(
|
||||
mToken, contentUri, packageName).asBinder());
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@@ -5855,28 +5858,55 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void setInputMethod(String id, IVoidResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback, () -> mImms.setInputMethod(mToken, id));
|
||||
public void setInputMethod(String id, AndroidFuture future /* T=Void */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Void> typedFuture = future;
|
||||
try {
|
||||
mImms.setInputMethod(mToken, id);
|
||||
typedFuture.complete(null);
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void setInputMethodAndSubtype(String id, InputMethodSubtype subtype,
|
||||
IVoidResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback,
|
||||
() -> mImms.setInputMethodAndSubtype(mToken, id, subtype));
|
||||
AndroidFuture future /* T=Void */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Void> typedFuture = future;
|
||||
try {
|
||||
mImms.setInputMethodAndSubtype(mToken, id, subtype);
|
||||
typedFuture.complete(null);
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void hideMySoftInput(int flags, IVoidResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback, () -> mImms.hideMySoftInput(mToken, flags));
|
||||
public void hideMySoftInput(int flags, AndroidFuture future /* T=Void */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Void> typedFuture = future;
|
||||
try {
|
||||
mImms.hideMySoftInput(mToken, flags);
|
||||
typedFuture.complete(null);
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void showMySoftInput(int flags, IVoidResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback, () -> mImms.showMySoftInput(mToken, flags));
|
||||
public void showMySoftInput(int flags, AndroidFuture future /* T=Void */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Void> typedFuture = future;
|
||||
try {
|
||||
mImms.showMySoftInput(mToken, flags);
|
||||
typedFuture.complete(null);
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@@ -5887,24 +5917,39 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void switchToPreviousInputMethod(IBooleanResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback, () -> mImms.switchToPreviousInputMethod(mToken));
|
||||
public void switchToPreviousInputMethod(AndroidFuture future /* T=Boolean */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Boolean> typedFuture = future;
|
||||
try {
|
||||
typedFuture.complete(mImms.switchToPreviousInputMethod(mToken));
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void switchToNextInputMethod(boolean onlyCurrentIme,
|
||||
IBooleanResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback,
|
||||
() -> mImms.switchToNextInputMethod(mToken, onlyCurrentIme));
|
||||
AndroidFuture future /* T=Boolean */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Boolean> typedFuture = future;
|
||||
try {
|
||||
typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme));
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void shouldOfferSwitchingToNextInputMethod(
|
||||
IBooleanResultCallback resultCallback) {
|
||||
CallbackUtils.onResult(resultCallback,
|
||||
() -> mImms.shouldOfferSwitchingToNextInputMethod(mToken));
|
||||
public void shouldOfferSwitchingToNextInputMethod(AndroidFuture future /* T=Boolean */) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AndroidFuture<Boolean> typedFuture = future;
|
||||
try {
|
||||
typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken));
|
||||
} catch (Throwable e) {
|
||||
typedFuture.completeExceptionally(e);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
|
||||
Reference in New Issue
Block a user