Merge "Use AndroidFuture instead"

This commit is contained in:
TreeHugger Robot
2021-08-29 22:29:14 +00:00
committed by Android (Google) Code Review
14 changed files with 210 additions and 754 deletions

View File

@@ -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) { }
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
/**

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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));
}
};
}
}

View File

@@ -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);
}

View File

@@ -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