Merge "Make IInputMethodPrivilegedOperations to oneway" into sc-dev

This commit is contained in:
Wilson Wu
2021-03-05 03:54:16 +00:00
committed by Android (Google) Code Review
7 changed files with 234 additions and 72 deletions

View File

@@ -225,4 +225,31 @@ public final class CallbackUtils {
callback.onResult();
} catch (RemoteException ignored) { }
}
/**
* A utility method using given {@link IIInputContentUriTokenResultCallback} to callback the
* result.
*
* @param callback {@link IIInputContentUriTokenResultCallback} to be called back.
* @param resultSupplier the supplier from which the result is provided.
*/
public static void onResult(@NonNull IIInputContentUriTokenResultCallback 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

@@ -443,6 +443,13 @@ public final class Completable {
return new Completable.InputMethodInfoList();
}
/**
* @return an instance of {@link Completable.IInputContentUriToken}.
*/
public static Completable.IInputContentUriToken createIInputContentUriToken() {
return new Completable.IInputContentUriToken();
}
/**
* @return an instance of {@link Completable.Void}.
*/
@@ -496,6 +503,12 @@ public final class Completable {
public static final class InputMethodInfoList
extends Values<List<android.view.inputmethod.InputMethodInfo>> { }
/**
* Completable object of {@link IInputContentUriToken>}.
*/
public static final class IInputContentUriToken
extends Values<com.android.internal.inputmethod.IInputContentUriToken> { }
/**
* 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 com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.ThrowableHolder;
oneway interface IIInputContentUriTokenResultCallback {
void onResult(in IInputContentUriToken result);
void onError(in ThrowableHolder exception);
}

View File

@@ -19,25 +19,31 @@ 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.IIInputContentUriTokenResultCallback;
import com.android.internal.inputmethod.IVoidResultCallback;
/**
* Defines priviledged operations that only the current IME is allowed to call.
* Actual operations are implemented and handled by InputMethodManagerService.
*/
interface IInputMethodPrivilegedOperations {
void setImeWindowStatus(int vis, int backDisposition);
void reportStartInput(in IBinder startInputToken);
IInputContentUriToken createInputContentUriToken(in Uri contentUri, in String packageName);
void reportFullscreenMode(boolean fullscreen);
void setInputMethod(String id);
void setInputMethodAndSubtype(String id, in InputMethodSubtype subtype);
void hideMySoftInput(int flags);
void showMySoftInput(int flags);
void updateStatusIcon(String packageName, int iconId);
boolean switchToPreviousInputMethod();
boolean switchToNextInputMethod(boolean onlyCurrentIme);
boolean shouldOfferSwitchingToNextInputMethod();
void notifyUserAction();
void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible);
oneway interface IInputMethodPrivilegedOperations {
void setImeWindowStatus(int vis, int backDisposition, in IVoidResultCallback resultCallback);
void reportStartInput(in IBinder startInputToken, in IVoidResultCallback resultCallback);
void createInputContentUriToken(in Uri contentUri, in String packageName,
in IIInputContentUriTokenResultCallback resultCallback);
void reportFullscreenMode(boolean fullscreen, in IVoidResultCallback resultCallback);
void setInputMethod(String id, in IVoidResultCallback resultCallback);
void setInputMethodAndSubtype(String id, in InputMethodSubtype subtype,
in IVoidResultCallback resultCallback);
void hideMySoftInput(int flags, in IVoidResultCallback resultCallback);
void showMySoftInput(int flags, in IVoidResultCallback resultCallback);
void updateStatusIcon(String packageName, int iconId, in IVoidResultCallback resultCallback);
void switchToPreviousInputMethod(in IBooleanResultCallback resultCallback);
void switchToNextInputMethod(boolean onlyCurrentIme, in IBooleanResultCallback resultCallback);
void shouldOfferSwitchingToNextInputMethod(in IBooleanResultCallback resultCallback);
void notifyUserAction(in IVoidResultCallback resultCallback);
void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible,
in IVoidResultCallback resultCallback);
}

View File

@@ -95,7 +95,8 @@ public final class InputMethodPrivilegedOperations {
}
/**
* Calls {@link IInputMethodPrivilegedOperations#setImeWindowStatus(int, int)}.
* Calls {@link IInputMethodPrivilegedOperations#setImeWindowStatus(int, int,
* IVoidResultCallback)}.
*
* @param vis visibility flags
* @param backDisposition disposition flags
@@ -112,14 +113,17 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.setImeWindowStatus(vis, backDisposition);
final Completable.Void value = Completable.createVoid();
ops.setImeWindowStatus(vis, backDisposition, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#reportStartInput(IBinder)}.
* Calls {@link IInputMethodPrivilegedOperations#reportStartInput(IBinder,
* IVoidResultCallback)}.
*
* @param startInputToken {@link IBinder} token to distinguish startInput session
*/
@@ -130,14 +134,17 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.reportStartInput(startInputToken);
final Completable.Void value = Completable.createVoid();
ops.reportStartInput(startInputToken, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String)}.
* Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String,
* IIInputContentUriTokenResultCallback)}.
*
* @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
@@ -151,7 +158,10 @@ public final class InputMethodPrivilegedOperations {
return null;
}
try {
return ops.createInputContentUriToken(contentUri, packageName);
final Completable.IInputContentUriToken value =
Completable.createIInputContentUriToken();
ops.createInputContentUriToken(contentUri, packageName, ResultCallbacks.of(value));
return Completable.getResult(value);
} 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.
@@ -161,7 +171,8 @@ public final class InputMethodPrivilegedOperations {
}
/**
* Calls {@link IInputMethodPrivilegedOperations#reportFullscreenMode(boolean)}.
* Calls {@link IInputMethodPrivilegedOperations#reportFullscreenMode(boolean,
* IVoidResultCallback)}.
*
* @param fullscreen {@code true} if the IME enters full screen mode
*/
@@ -172,14 +183,17 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.reportFullscreenMode(fullscreen);
final Completable.Void value = Completable.createVoid();
ops.reportFullscreenMode(fullscreen, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#updateStatusIcon(String, int)}.
* Calls {@link IInputMethodPrivilegedOperations#updateStatusIcon(String, int,
* IVoidResultCallback)}.
*
* @param packageName package name from which the status icon should be loaded
* @param iconResId resource ID of the icon to be loaded
@@ -191,14 +205,16 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.updateStatusIcon(packageName, iconResId);
final Completable.Void value = Completable.createVoid();
ops.updateStatusIcon(packageName, iconResId, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#setInputMethod(String)}.
* Calls {@link IInputMethodPrivilegedOperations#setInputMethod(String, IVoidResultCallback)}.
*
* @param id IME ID of the IME to switch to
* @see android.view.inputmethod.InputMethodInfo#getId()
@@ -210,7 +226,9 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.setInputMethod(id);
final Completable.Void value = Completable.createVoid();
ops.setInputMethod(id, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -218,7 +236,7 @@ public final class InputMethodPrivilegedOperations {
/**
* Calls {@link IInputMethodPrivilegedOperations#setInputMethodAndSubtype(String,
* InputMethodSubtype)}
* InputMethodSubtype, IVoidResultCallback)}
*
* @param id IME ID of the IME to switch to
* @param subtype {@link InputMethodSubtype} to switch to
@@ -231,14 +249,16 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.setInputMethodAndSubtype(id, subtype);
final Completable.Void value = Completable.createVoid();
ops.setInputMethodAndSubtype(id, subtype, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#hideMySoftInput(int)}
* Calls {@link IInputMethodPrivilegedOperations#hideMySoftInput(int, IVoidResultCallback)}
*
* @param flags additional operating flags
* @see android.view.inputmethod.InputMethodManager#HIDE_IMPLICIT_ONLY
@@ -251,14 +271,16 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.hideMySoftInput(flags);
final Completable.Void value = Completable.createVoid();
ops.hideMySoftInput(flags, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#showMySoftInput(int)}
* Calls {@link IInputMethodPrivilegedOperations#showMySoftInput(int, IVoidResultCallback)}
*
* @param flags additional operating flags
* @see android.view.inputmethod.InputMethodManager#SHOW_IMPLICIT
@@ -271,14 +293,17 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.showMySoftInput(flags);
final Completable.Void value = Completable.createVoid();
ops.showMySoftInput(flags, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#switchToPreviousInputMethod()}
* Calls {@link IInputMethodPrivilegedOperations#switchToPreviousInputMethod(
* IBooleanResultCallback)}
*
* @return {@code true} if handled
*/
@@ -289,14 +314,17 @@ public final class InputMethodPrivilegedOperations {
return false;
}
try {
return ops.switchToPreviousInputMethod();
final Completable.Boolean value = Completable.createBoolean();
ops.switchToPreviousInputMethod(ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#switchToNextInputMethod(boolean)}
* Calls {@link IInputMethodPrivilegedOperations#switchToNextInputMethod(boolean,
* IBooleanResultCallback)}
*
* @param onlyCurrentIme {@code true} to switch to a {@link InputMethodSubtype} within the same
* IME
@@ -309,14 +337,17 @@ public final class InputMethodPrivilegedOperations {
return false;
}
try {
return ops.switchToNextInputMethod(onlyCurrentIme);
final Completable.Boolean value = Completable.createBoolean();
ops.switchToNextInputMethod(onlyCurrentIme, ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#shouldOfferSwitchingToNextInputMethod()}
* Calls {@link IInputMethodPrivilegedOperations#shouldOfferSwitchingToNextInputMethod(
* IBooleanResultCallback)}
*
* @return {@code true} if the IEM should offer a way to globally switch IME
*/
@@ -327,14 +358,16 @@ public final class InputMethodPrivilegedOperations {
return false;
}
try {
return ops.shouldOfferSwitchingToNextInputMethod();
final Completable.Boolean value = Completable.createBoolean();
ops.shouldOfferSwitchingToNextInputMethod(ResultCallbacks.of(value));
return Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#notifyUserAction()}
* Calls {@link IInputMethodPrivilegedOperations#notifyUserAction(IVoidResultCallback)}
*/
@AnyThread
public void notifyUserAction() {
@@ -343,14 +376,17 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.notifyUserAction();
final Completable.Void value = Completable.createVoid();
ops.notifyUserAction(ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean)}.
* Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean,
* IVoidResultCallback)}.
*
* @param showOrHideInputToken placeholder token that maps to window requesting
* {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} or
@@ -365,7 +401,9 @@ public final class InputMethodPrivilegedOperations {
return;
}
try {
ops.applyImeVisibility(showOrHideInputToken, setVisible);
final Completable.Void value = Completable.createVoid();
ops.applyImeVisibility(showOrHideInputToken, setVisible, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -387,4 +387,41 @@ public final class ResultCallbacks {
}
};
}
/**
* Creates {@link IIInputContentUriTokenResultCallback.Stub} that is to set
* {@link Completable.IInputContentUriToken} when receiving the result.
*
* @param value {@link Completable.IInputContentUriToken} to be set when receiving the result.
* @return {@link IIInputContentUriTokenResultCallback.Stub} that can be passed as a binder IPC
* parameter.
*/
@AnyThread
public static IIInputContentUriTokenResultCallback.Stub of(
@NonNull Completable.IInputContentUriToken value) {
final AtomicReference<WeakReference<Completable.IInputContentUriToken>>
atomicRef = new AtomicReference<>(new WeakReference<>(value));
return new IIInputContentUriTokenResultCallback.Stub() {
@BinderThread
@Override
public void onResult(IInputContentUriToken result) {
final Completable.IInputContentUriToken value = unwrap(atomicRef);
if (value == null) {
return;
}
value.onComplete(result);
}
@BinderThread
@Override
public void onError(ThrowableHolder throwableHolder) {
final Completable.IInputContentUriToken value = unwrap(atomicRef);
if (value == null) {
return;
}
value.onError(throwableHolder);
}
};
}
}

View File

@@ -159,6 +159,7 @@ 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.inputmethod.IIInputContentUriTokenResultCallback;
import com.android.internal.inputmethod.IInputBindResultResultCallback;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodInfoListResultCallback;
@@ -5883,87 +5884,102 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@Override
public void setImeWindowStatus(int vis, int backDisposition) {
mImms.setImeWindowStatus(mToken, vis, backDisposition);
public void setImeWindowStatus(int vis, int backDisposition,
IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.setImeWindowStatus(mToken, vis, backDisposition));
}
@BinderThread
@Override
public void reportStartInput(IBinder startInputToken) {
mImms.reportStartInput(mToken, startInputToken);
public void reportStartInput(IBinder startInputToken, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.reportStartInput(mToken, startInputToken));
}
@BinderThread
@Override
public IInputContentUriToken createInputContentUriToken(Uri contentUri,
String packageName) {
return mImms.createInputContentUriToken(mToken, contentUri, packageName);
public void createInputContentUriToken(Uri contentUri, String packageName,
IIInputContentUriTokenResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.createInputContentUriToken(mToken, contentUri, packageName));
}
@BinderThread
@Override
public void reportFullscreenMode(boolean fullscreen) {
mImms.reportFullscreenMode(mToken, fullscreen);
public void reportFullscreenMode(boolean fullscreen, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.reportFullscreenMode(mToken, fullscreen));
}
@BinderThread
@Override
public void setInputMethod(String id) {
mImms.setInputMethod(mToken, id);
public void setInputMethod(String id, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> mImms.setInputMethod(mToken, id));
}
@BinderThread
@Override
public void setInputMethodAndSubtype(String id, InputMethodSubtype subtype) {
mImms.setInputMethodAndSubtype(mToken, id, subtype);
public void setInputMethodAndSubtype(String id, InputMethodSubtype subtype,
IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.setInputMethodAndSubtype(mToken, id, subtype));
}
@BinderThread
@Override
public void hideMySoftInput(int flags) {
mImms.hideMySoftInput(mToken, flags);
public void hideMySoftInput(int flags, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> mImms.hideMySoftInput(mToken, flags));
}
@BinderThread
@Override
public void showMySoftInput(int flags) {
mImms.showMySoftInput(mToken, flags);
public void showMySoftInput(int flags, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> mImms.showMySoftInput(mToken, flags));
}
@BinderThread
@Override
public void updateStatusIcon(String packageName, @DrawableRes int iconId) {
mImms.updateStatusIcon(mToken, packageName, iconId);
public void updateStatusIcon(String packageName, @DrawableRes int iconId,
IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.updateStatusIcon(mToken, packageName, iconId));
}
@BinderThread
@Override
public boolean switchToPreviousInputMethod() {
return mImms.switchToPreviousInputMethod(mToken);
public void switchToPreviousInputMethod(IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> mImms.switchToPreviousInputMethod(mToken));
}
@BinderThread
@Override
public boolean switchToNextInputMethod(boolean onlyCurrentIme) {
return mImms.switchToNextInputMethod(mToken, onlyCurrentIme);
public void switchToNextInputMethod(boolean onlyCurrentIme,
IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.switchToNextInputMethod(mToken, onlyCurrentIme));
}
@BinderThread
@Override
public boolean shouldOfferSwitchingToNextInputMethod() {
return mImms.shouldOfferSwitchingToNextInputMethod(mToken);
public void shouldOfferSwitchingToNextInputMethod(
IBooleanResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.shouldOfferSwitchingToNextInputMethod(mToken));
}
@BinderThread
@Override
public void notifyUserAction() {
mImms.notifyUserAction(mToken);
public void notifyUserAction(IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> mImms.notifyUserAction(mToken));
}
@BinderThread
@Override
public void applyImeVisibility(IBinder windowToken, boolean setVisible) {
mImms.applyImeVisibility(mToken, windowToken, setVisible);
public void applyImeVisibility(IBinder windowToken, boolean setVisible,
IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback,
() -> mImms.applyImeVisibility(mToken, windowToken, setVisible));
}
}
}