From 8e0d398ab9018936ce34b3d2eb44ee997da20307 Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Mon, 28 Dec 2020 18:41:06 +0800 Subject: [PATCH] Make IInputMethodManager to oneway (8/N) Add IVoidResultCallback mechanism to emulate current behavior. Bug: 163453493 Test: Manual test with keyboard Test: atest CtsInputMethodTestCases Change-Id: I009d3a6e09c98166c08e8b9b318d821be36c42a7 --- .../internal/inputmethod/CallbackUtils.java | 25 +++++++++ .../internal/inputmethod/Completable.java | 54 +++++++++++++++++++ .../inputmethod/IVoidResultCallback.aidl | 24 +++++++++ .../internal/inputmethod/ResultCallbacks.java | 35 ++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 core/java/com/android/internal/inputmethod/IVoidResultCallback.aidl diff --git a/core/java/com/android/internal/inputmethod/CallbackUtils.java b/core/java/com/android/internal/inputmethod/CallbackUtils.java index 248feb8bcbd7c..e9e39db904376 100644 --- a/core/java/com/android/internal/inputmethod/CallbackUtils.java +++ b/core/java/com/android/internal/inputmethod/CallbackUtils.java @@ -200,4 +200,29 @@ public final class CallbackUtils { 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 resultSupplier the supplier from which the result is provided. + */ + public static void onResult(@NonNull IVoidResultCallback callback, + @NonNull Supplier resultSupplier) { + Throwable exception = null; + + try { + resultSupplier.get(); + } catch (Throwable throwable) { + exception = throwable; + } + + try { + if (exception != null) { + callback.onError(ThrowableHolder.of(exception)); + return; + } + callback.onResult(); + } catch (RemoteException ignored) { } + } } diff --git a/core/java/com/android/internal/inputmethod/Completable.java b/core/java/com/android/internal/inputmethod/Completable.java index 1913fcdc9ba94..b82ba81328893 100644 --- a/core/java/com/android/internal/inputmethod/Completable.java +++ b/core/java/com/android/internal/inputmethod/Completable.java @@ -285,6 +285,42 @@ public final class Completable { } } + /** + * Completable object of {@link java.lang.Void}. + */ + public static final class Void extends ValueBase { + /** + * Notify when this completable object callback. + */ + @AnyThread + @Override + protected void onComplete() { + synchronized (mStateLock) { + switch (mState) { + case CompletionState.NOT_COMPLETED: + mState = CompletionState.COMPLETED_WITH_VALUE; + break; + default: + throw new UnsupportedOperationException( + "onComplete() is not allowed on state=" + stateToString(mState)); + } + } + super.onComplete(); + } + + /** + * @throws RuntimeException when called while {@link #onError} happened. + * @throws UnsupportedOperationException when called while {@link #hasValue()} returns + * {@code false}. + */ + @AnyThread + public void getValue() { + synchronized (mStateLock) { + enforceGetValueLocked(); + } + } + } + /** * Base class of completable object types. * @@ -395,6 +431,13 @@ public final class Completable { return new Completable.InputMethodInfoList(); } + /** + * @return an instance of {@link Completable.Void}. + */ + public static Completable.Void createVoid() { + return new Completable.Void(); + } + /** * Completable object of {@link java.lang.Boolean}. */ @@ -464,6 +507,17 @@ public final class Completable { return value.getValue(); } + /** + * Await the result by the {@link Completable.Void}. + * + * Check the result once {@link ValueBase#onComplete()} + */ + @AnyThread + public static void getResult(@NonNull Completable.Void value) { + value.await(); + value.getValue(); + } + /** * Await the result by the {@link Completable.Int}, and log it if there is no result after * given timeout. diff --git a/core/java/com/android/internal/inputmethod/IVoidResultCallback.aidl b/core/java/com/android/internal/inputmethod/IVoidResultCallback.aidl new file mode 100644 index 0000000000000..0b25a2b886c9a --- /dev/null +++ b/core/java/com/android/internal/inputmethod/IVoidResultCallback.aidl @@ -0,0 +1,24 @@ +/* + * 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); +} \ No newline at end of file diff --git a/core/java/com/android/internal/inputmethod/ResultCallbacks.java b/core/java/com/android/internal/inputmethod/ResultCallbacks.java index 6ce851b59ccda..2a48c1f60aa96 100644 --- a/core/java/com/android/internal/inputmethod/ResultCallbacks.java +++ b/core/java/com/android/internal/inputmethod/ResultCallbacks.java @@ -352,4 +352,39 @@ public final class ResultCallbacks { } }; } + + /** + * Creates {@link IVoidResultCallback.Stub} that is to set {@link Completable.Void} when + * receiving the result. + * + * @param value {@link Completable.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 of(@NonNull Completable.Void value) { + final AtomicReference> atomicRef = + new AtomicReference<>(new WeakReference<>(value)); + + return new IVoidResultCallback.Stub() { + @BinderThread + @Override + public void onResult() { + final Completable.Void value = unwrap(atomicRef); + if (value == null) { + return; + } + value.onComplete(); + } + + @BinderThread + @Override + public void onError(ThrowableHolder throwableHolder) { + final Completable.Void value = unwrap(atomicRef); + if (value == null) { + return; + } + value.onError(throwableHolder); + } + }; + } }