Merge "Make IInputMethodManager to oneway (6/N)"

This commit is contained in:
TreeHugger Robot
2020-12-23 03:52:54 +00:00
committed by Android (Google) Code Review
9 changed files with 306 additions and 63 deletions

View File

@@ -1430,8 +1430,13 @@ public final class InputMethodManager {
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
boolean allowsImplicitlySelectedSubtypes) {
try {
return mService.getEnabledInputMethodSubtypeList(
imi == null ? null : imi.getId(), allowsImplicitlySelectedSubtypes);
final Completable.InputMethodSubtypeList value =
Completable.createInputMethodSubtypeList();
mService.getEnabledInputMethodSubtypeList(
imi == null ? null : imi.getId(),
allowsImplicitlySelectedSubtypes,
ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2970,7 +2975,9 @@ public final class InputMethodManager {
*/
public InputMethodSubtype getCurrentInputMethodSubtype() {
try {
return mService.getCurrentInputMethodSubtype();
final Completable.InputMethodSubtype value = Completable.createInputMethodSubtype();
mService.getCurrentInputMethodSubtype(ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3019,7 +3026,11 @@ public final class InputMethodManager {
}
final List<InputMethodSubtype> enabledSubtypes;
try {
enabledSubtypes = mService.getEnabledInputMethodSubtypeList(imeId, true);
final Completable.InputMethodSubtypeList value =
Completable.createInputMethodSubtypeList();
mService.getEnabledInputMethodSubtypeList(
imeId, true, ResultCallbacks.of(value));
enabledSubtypes = Completable.getResult(value);
} catch (RemoteException e) {
return false;
}
@@ -3214,7 +3225,9 @@ public final class InputMethodManager {
public InputMethodSubtype getLastInputMethodSubtype() {
try {
return mService.getLastInputMethodSubtype();
final Completable.InputMethodSubtype value = Completable.createInputMethodSubtype();
mService.getLastInputMethodSubtype(ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -19,9 +19,11 @@ package com.android.internal.inputmethod;
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.os.RemoteException;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.view.InputBindResult;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
@@ -67,7 +69,7 @@ public final class CallbackUtils {
/**
* A utility method using given {@link IBooleanResultCallback} to callback the result.
*
* @param callback {@link IInputBindResultResultCallback} to be called back.
* @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,
@@ -89,4 +91,58 @@ public final class CallbackUtils {
callback.onResult(result);
} catch (RemoteException ignored) { }
}
/**
* A utility method using given {@link IInputMethodSubtypeResultCallback} to callback the
* result.
*
* @param callback {@link IInputMethodSubtypeResultCallback} to be called back.
* @param resultSupplier the supplier from which the result is provided.
*/
public static void onResult(@NonNull IInputMethodSubtypeResultCallback callback,
@NonNull Supplier<InputMethodSubtype> resultSupplier) {
InputMethodSubtype 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) { }
}
/**
* A utility method using given {@link IInputMethodSubtypeListResultCallback} to callback the
* result.
*
* @param callback {@link IInputMethodSubtypeListResultCallback} to be called back.
* @param resultSupplier the supplier from which the result is provided.
*/
public static void onResult(@NonNull IInputMethodSubtypeListResultCallback callback,
@NonNull Supplier<List<InputMethodSubtype>> resultSupplier) {
List<InputMethodSubtype> 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

@@ -23,10 +23,12 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.annotations.GuardedBy;
import java.lang.annotation.Retention;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -372,6 +374,20 @@ public final class Completable {
return new Completable.InputBindResult();
}
/**
* @return an instance of {@link Completable.InputMethodSubtype}.
*/
public static Completable.InputMethodSubtype createInputMethodSubtype() {
return new Completable.InputMethodSubtype();
}
/**
* @return an instance of {@link Completable.InputMethodSubtypeList}.
*/
public static Completable.InputMethodSubtypeList createInputMethodSubtypeList() {
return new Completable.InputMethodSubtypeList();
}
/**
* Completable object of {@link java.lang.Boolean}.
*/
@@ -400,6 +416,18 @@ public final class Completable {
public static final class InputBindResult
extends Values<com.android.internal.view.InputBindResult> { }
/**
* Completable object of {@link android.view.inputmethod.InputMethodSubtype}.
*/
public static final class InputMethodSubtype
extends Values<android.view.inputmethod.InputMethodSubtype> { }
/**
* Completable object of {@link List<android.view.inputmethod.InputMethodSubtype>}.
*/
public static final class InputMethodSubtypeList
extends Values<List<android.view.inputmethod.InputMethodSubtype>> { }
/**
* Await the result by the {@link Completable.Values}.
*

View File

@@ -0,0 +1,25 @@
/*
* 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.InputMethodSubtype;
import com.android.internal.inputmethod.ThrowableHolder;
oneway interface IInputMethodSubtypeListResultCallback {
void onResult(in List<InputMethodSubtype> result);
void onError(in ThrowableHolder exception);
}

View File

@@ -0,0 +1,25 @@
/*
* 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.InputMethodSubtype;
import com.android.internal.inputmethod.ThrowableHolder;
oneway interface IInputMethodSubtypeResultCallback {
void onResult(in InputMethodSubtype result);
void onError(in ThrowableHolder exception);
}

View File

@@ -20,10 +20,12 @@ import android.annotation.AnyThread;
import android.annotation.BinderThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.view.InputBindResult;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -228,4 +230,78 @@ public final class ResultCallbacks {
}
};
}
/**
* Creates {@link IInputMethodSubtypeResultCallback.Stub} that is to set
* {@link Completable.InputMethodSubtype} when receiving the result.
*
* @param value {@link Completable.InputMethodSubtype} to be set when receiving the result.
* @return {@link IInputMethodSubtypeResultCallback.Stub} that can be passed as a binder
* IPC parameter.
*/
@AnyThread
public static IInputMethodSubtypeResultCallback.Stub of(
@NonNull Completable.InputMethodSubtype value) {
final AtomicReference<WeakReference<Completable.InputMethodSubtype>>
atomicRef = new AtomicReference<>(new WeakReference<>(value));
return new IInputMethodSubtypeResultCallback.Stub() {
@BinderThread
@Override
public void onResult(InputMethodSubtype result) {
final Completable.InputMethodSubtype value = unwrap(atomicRef);
if (value == null) {
return;
}
value.onComplete(result);
}
@BinderThread
@Override
public void onError(ThrowableHolder throwableHolder) {
final Completable.InputMethodSubtype value = unwrap(atomicRef);
if (value == null) {
return;
}
value.onError(throwableHolder);
}
};
}
/**
* Creates {@link IInputMethodSubtypeListResultCallback.Stub} that is to set
* {@link Completable.InputMethodSubtypeList} when receiving the result.
*
* @param value {@link Completable.InputMethodSubtypeList} to be set when receiving the result.
* @return {@link IInputMethodSubtypeListResultCallback.Stub} that can be passed as a binder
* IPC parameter.
*/
@AnyThread
public static IInputMethodSubtypeListResultCallback.Stub of(
@NonNull Completable.InputMethodSubtypeList value) {
final AtomicReference<WeakReference<Completable.InputMethodSubtypeList>>
atomicRef = new AtomicReference<>(new WeakReference<>(value));
return new IInputMethodSubtypeListResultCallback.Stub() {
@BinderThread
@Override
public void onResult(List<InputMethodSubtype> result) {
final Completable.InputMethodSubtypeList value = unwrap(atomicRef);
if (value == null) {
return;
}
value.onComplete(result);
}
@BinderThread
@Override
public void onError(ThrowableHolder throwableHolder) {
final Completable.InputMethodSubtypeList value = unwrap(atomicRef);
if (value == null) {
return;
}
value.onError(throwableHolder);
}
};
}
}

View File

@@ -26,6 +26,8 @@ import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.inputmethod.IBooleanResultCallback;
import com.android.internal.inputmethod.IInputBindResultResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeListResultCallback;
/**
* Public interface to the global input method manager, used by all client
@@ -39,9 +41,9 @@ interface IInputMethodManager {
List<InputMethodInfo> getInputMethodList(int userId);
// TODO: Use ParceledListSlice instead
List<InputMethodInfo> getEnabledInputMethodList(int userId);
List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
boolean allowsImplicitlySelectedSubtypes);
InputMethodSubtype getLastInputMethodSubtype();
void getEnabledInputMethodSubtypeList(in String imiId, boolean allowsImplicitlySelectedSubtypes,
in IInputMethodSubtypeListResultCallback resultCallback);
void getLastInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback);
void showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
in ResultReceiver resultReceiver, in IBooleanResultCallback resultCallback);
@@ -66,7 +68,7 @@ interface IInputMethodManager {
int displayId);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
void isInputMethodPickerShownForTest(in IBooleanResultCallback resultCallback);
InputMethodSubtype getCurrentInputMethodSubtype();
void getCurrentInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback);
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
// This is kept due to @UnsupportedAppUsage.
// TODO(Bug 113914148): Consider removing this.

View File

@@ -163,6 +163,8 @@ import com.android.internal.inputmethod.IBooleanResultCallback;
import com.android.internal.inputmethod.IInputBindResultResultCallback;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.IInputMethodSubtypeListResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeResultCallback;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
@@ -2159,27 +2161,34 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
/**
* @param imiId if null, returns enabled subtypes for the current imi
* @return enabled subtypes of the specified imi
* Gets enabled subtypes of the specified {@link InputMethodInfo}.
*
* @param imiId if null, returns enabled subtypes for the current {@link InputMethodInfo}.
* @param allowsImplicitlySelectedSubtypes {@code true} to return the implicitly selected
* subtypes.
* @param resultCallback to callback the result.
*/
@Override
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
boolean allowsImplicitlySelectedSubtypes) {
final int callingUserId = UserHandle.getCallingUserId();
synchronized (mMethodMap) {
final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
return Collections.emptyList();
public void getEnabledInputMethodSubtypeList(String imiId,
boolean allowsImplicitlySelectedSubtypes,
IInputMethodSubtypeListResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
final int callingUserId = UserHandle.getCallingUserId();
synchronized (mMethodMap) {
final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId,
mSettings.getCurrentUserId(), null);
if (resolvedUserIds.length != 1) {
return Collections.emptyList();
}
final long ident = Binder.clearCallingIdentity();
try {
return getEnabledInputMethodSubtypeListLocked(imiId,
allowsImplicitlySelectedSubtypes, resolvedUserIds[0]);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
final long ident = Binder.clearCallingIdentity();
try {
return getEnabledInputMethodSubtypeListLocked(imiId,
allowsImplicitlySelectedSubtypes, resolvedUserIds[0]);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
});
}
@GuardedBy("mMethodMap")
@@ -3892,29 +3901,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
public InputMethodSubtype getLastInputMethodSubtype() {
synchronized (mMethodMap) {
if (!calledFromValidUserLocked()) {
return null;
}
final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
// TODO: Handle the case of the last IME with no subtypes
if (lastIme == null || TextUtils.isEmpty(lastIme.first)
|| TextUtils.isEmpty(lastIme.second)) return null;
final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
if (lastImi == null) return null;
try {
final int lastSubtypeHash = Integer.parseInt(lastIme.second);
final int lastSubtypeId =
InputMethodUtils.getSubtypeIdFromHashCode(lastImi, lastSubtypeHash);
if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
public void getLastInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
synchronized (mMethodMap) {
if (!calledFromValidUserLocked()) {
return null;
}
final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
// TODO: Handle the case of the last IME with no subtypes
if (lastIme == null || TextUtils.isEmpty(lastIme.first)
|| TextUtils.isEmpty(lastIme.second)) return null;
final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
if (lastImi == null) return null;
try {
final int lastSubtypeHash = Integer.parseInt(lastIme.second);
final int lastSubtypeId =
InputMethodUtils.getSubtypeIdFromHashCode(lastImi, lastSubtypeHash);
if (lastSubtypeId < 0 || lastSubtypeId >= lastImi.getSubtypeCount()) {
return null;
}
return lastImi.getSubtypeAt(lastSubtypeId);
} catch (NumberFormatException e) {
return null;
}
return lastImi.getSubtypeAt(lastSubtypeId);
} catch (NumberFormatException e) {
return null;
}
}
});
}
@Override
@@ -4950,17 +4961,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
/**
* @return Return the current subtype of this input method.
* Gets the current subtype of this input method.
*
* @param resultCallback to callback the result.
*/
@Override
public InputMethodSubtype getCurrentInputMethodSubtype() {
synchronized (mMethodMap) {
// TODO: Make this work even for non-current users?
if (!calledFromValidUserLocked()) {
return null;
public void getCurrentInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
synchronized (mMethodMap) {
// TODO: Make this work even for non-current users?
if (!calledFromValidUserLocked()) {
return null;
}
return getCurrentInputMethodSubtypeLocked();
}
return getCurrentInputMethodSubtypeLocked();
}
});
}
InputMethodSubtype getCurrentInputMethodSubtypeLocked() {

View File

@@ -75,6 +75,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.CallbackUtils;
import com.android.internal.inputmethod.IBooleanResultCallback;
import com.android.internal.inputmethod.IInputBindResultResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeListResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeResultCallback;
import com.android.internal.inputmethod.IMultiClientInputMethod;
import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.IMultiClientInputMethodSession;
@@ -1475,17 +1477,18 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
boolean allowsImplicitlySelectedSubtypes) {
public void getEnabledInputMethodSubtypeList(String imiId,
boolean allowsImplicitlySelectedSubtypes,
IInputMethodSubtypeListResultCallback resultCallback) {
reportNotSupported();
return Collections.emptyList();
CallbackUtils.onResult(resultCallback, Collections::emptyList);
}
@BinderThread
@Override
public InputMethodSubtype getLastInputMethodSubtype() {
public void getLastInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) {
reportNotSupported();
return null;
CallbackUtils.onResult(resultCallback, () -> null);
}
@BinderThread
@@ -1793,9 +1796,9 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
public InputMethodSubtype getCurrentInputMethodSubtype() {
public void getCurrentInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) {
reportNotSupported();
return null;
CallbackUtils.onResult(resultCallback, () -> null);
}
@BinderThread