Make IInputMethodManager to oneway (9/N)

Apply following methods to IVoidResultCallback to emulate
current behavior before we change them to one-way.

-. showInputMethodPickerFromClient
-. showInputMethodPickerFromSystem
-. showInputMethodAndSubtypeEnablerFromClient
-. reportActivityView

Bug: 163453493
Test: Manual test with keyboard
Test: atest CtsInputMethodTestCases
Test: atest CtsWindowManagerDeviceTestCases:ActivityViewTest
Change-Id: Id516fd1c961f43ac3e139c88d7ed004c188d458b
This commit is contained in:
Wilson Wu
2021-01-12 17:53:36 +08:00
parent 4f4ec2fa0c
commit 0a32fd21ef
5 changed files with 153 additions and 123 deletions

View File

@@ -2926,7 +2926,10 @@ public final class InputMethodManager {
? SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES
: SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES;
try {
mService.showInputMethodPickerFromSystem(mClient, mode, displayId);
final Completable.Void value = Completable.createVoid();
mService.showInputMethodPickerFromSystem(
mClient, mode, displayId, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2934,7 +2937,10 @@ public final class InputMethodManager {
private void showInputMethodPickerLocked() {
try {
mService.showInputMethodPickerFromClient(mClient, SHOW_IM_PICKER_MODE_AUTO);
final Completable.Void value = Completable.createVoid();
mService.showInputMethodPickerFromClient(
mClient, SHOW_IM_PICKER_MODE_AUTO, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2970,7 +2976,10 @@ public final class InputMethodManager {
*/
public void showInputMethodAndSubtypeEnabler(String imiId) {
try {
mService.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId);
final Completable.Void value = Completable.createVoid();
mService.showInputMethodAndSubtypeEnablerFromClient(
mClient, imiId, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3132,7 +3141,10 @@ public final class InputMethodManager {
matrixValues = new float[9];
matrix.getValues(matrixValues);
}
mService.reportActivityView(mClient, childDisplayId, matrixValues);
final Completable.Void value = Completable.createVoid();
mService.reportActivityView(
mClient, childDisplayId, matrixValues, ResultCallbacks.of(value));
Completable.getResult(value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -205,14 +205,14 @@ public final class CallbackUtils {
* 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.
* @param runnable to execute the given method
*/
public static void onResult(@NonNull IVoidResultCallback callback,
@NonNull Supplier<Void> resultSupplier) {
@NonNull Runnable runnable) {
Throwable exception = null;
try {
resultSupplier.get();
runnable.run();
} catch (Throwable throwable) {
exception = throwable;
}

View File

@@ -30,6 +30,7 @@ import com.android.internal.inputmethod.IInputMethodInfoListResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeListResultCallback;
import com.android.internal.inputmethod.IIntResultCallback;
import com.android.internal.inputmethod.IVoidResultCallback;
/**
* Public interface to the global input method manager, used by all client
@@ -66,10 +67,11 @@ interface IInputMethodManager {
in IInputBindResultResultCallback inputBindResult);
void showInputMethodPickerFromClient(in IInputMethodClient client,
int auxiliarySubtypeMode);
int auxiliarySubtypeMode, in IVoidResultCallback resultCallback);
void showInputMethodPickerFromSystem(in IInputMethodClient client, int auxiliarySubtypeMode,
int displayId);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
int displayId, in IVoidResultCallback resultCallback);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId,
in IVoidResultCallback resultCallback);
void isInputMethodPickerShownForTest(in IBooleanResultCallback resultCallback);
void getCurrentInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback);
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
@@ -78,7 +80,7 @@ interface IInputMethodManager {
void getInputMethodWindowVisibleHeight(IIntResultCallback resultCallback);
void reportActivityView(in IInputMethodClient parentClient, int childDisplayId,
in float[] matrixValues);
in float[] matrixValues, in IVoidResultCallback resultCallback);
oneway void reportPerceptible(in IBinder windowToken, boolean perceptible);
/** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */

View File

@@ -167,6 +167,7 @@ import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.IInputMethodSubtypeListResultCallback;
import com.android.internal.inputmethod.IInputMethodSubtypeResultCallback;
import com.android.internal.inputmethod.IIntResultCallback;
import com.android.internal.inputmethod.IVoidResultCallback;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
@@ -3720,38 +3721,43 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
public void showInputMethodPickerFromClient(
IInputMethodClient client, int auxiliarySubtypeMode) {
synchronized (mMethodMap) {
if (!calledFromValidUserLocked()) {
return;
}
if(!canShowInputMethodPickerLocked(client)) {
Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
+ Binder.getCallingUid() + ": " + client);
return;
}
public void showInputMethodPickerFromClient(IInputMethodClient client, int auxiliarySubtypeMode,
IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
synchronized (mMethodMap) {
if (!calledFromValidUserLocked()) {
return;
}
if (!canShowInputMethodPickerLocked(client)) {
Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
+ Binder.getCallingUid() + ": " + client);
return;
}
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
mHandler.sendMessage(mCaller.obtainMessageII(
MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode,
(mCurClient != null) ? mCurClient.selfReportedDisplayId : DEFAULT_DISPLAY));
}
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
mHandler.sendMessage(mCaller.obtainMessageII(
MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode,
(mCurClient != null) ? mCurClient.selfReportedDisplayId : DEFAULT_DISPLAY));
}
});
}
@Override
public void showInputMethodPickerFromSystem(IInputMethodClient client, int auxiliarySubtypeMode,
int displayId) {
if (mContext.checkCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(
"showInputMethodPickerFromSystem requires WRITE_SECURE_SETTINGS permission");
}
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
mHandler.sendMessage(mCaller.obtainMessageII(
MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId));
int displayId, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
if (mContext.checkCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(
"showInputMethodPickerFromSystem requires WRITE_SECURE_SETTINGS "
+ "permission");
}
// Always call subtype picker, because subtype picker is a superset of input method
// picker.
mHandler.sendMessage(mCaller.obtainMessageII(
MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId));
});
}
/**
@@ -3795,15 +3801,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void showInputMethodAndSubtypeEnablerFromClient(
IInputMethodClient client, String inputMethodId) {
synchronized (mMethodMap) {
// TODO(yukawa): Should we verify the display ID?
if (!calledFromValidUserLocked()) {
return;
IInputMethodClient client, String inputMethodId, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
synchronized (mMethodMap) {
// TODO(yukawa): Should we verify the display ID?
if (!calledFromValidUserLocked()) {
return;
}
executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
MSG_SHOW_IM_SUBTYPE_ENABLER, inputMethodId));
}
executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
MSG_SHOW_IM_SUBTYPE_ENABLER, inputMethodId));
}
});
}
@BinderThread
@@ -4011,84 +4019,87 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void reportActivityView(IInputMethodClient parentClient, int childDisplayId,
float[] matrixValues) {
final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(childDisplayId);
if (displayInfo == null) {
throw new IllegalArgumentException(
"Cannot find display for non-existent displayId: " + childDisplayId);
}
final int callingUid = Binder.getCallingUid();
if (callingUid != displayInfo.ownerUid) {
throw new SecurityException("The caller doesn't own the display.");
}
synchronized (mMethodMap) {
final ClientState cs = mClients.get(parentClient.asBinder());
if (cs == null) {
return;
float[] matrixValues, IVoidResultCallback resultCallback) {
CallbackUtils.onResult(resultCallback, () -> {
final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(childDisplayId);
if (displayInfo == null) {
throw new IllegalArgumentException(
"Cannot find display for non-existent displayId: " + childDisplayId);
}
final int callingUid = Binder.getCallingUid();
if (callingUid != displayInfo.ownerUid) {
throw new SecurityException("The caller doesn't own the display.");
}
// null matrixValues means that the entry needs to be removed.
if (matrixValues == null) {
final ActivityViewInfo info = mActivityViewDisplayIdToParentMap.get(childDisplayId);
if (info == null) {
synchronized (mMethodMap) {
final ClientState cs = mClients.get(parentClient.asBinder());
if (cs == null) {
return;
}
if (info.mParentClient != cs) {
throw new SecurityException("Only the owner client can clear"
+ " ActivityViewGeometry for display #" + childDisplayId);
}
mActivityViewDisplayIdToParentMap.remove(childDisplayId);
return;
}
ActivityViewInfo info = mActivityViewDisplayIdToParentMap.get(childDisplayId);
if (info != null && info.mParentClient != cs) {
throw new InvalidParameterException("Display #" + childDisplayId
+ " is already registered by " + info.mParentClient);
}
if (info == null) {
if (!mWindowManagerInternal.isUidAllowedOnDisplay(childDisplayId, cs.uid)) {
throw new SecurityException(cs + " cannot access to display #"
+ childDisplayId);
}
info = new ActivityViewInfo(cs, new Matrix());
mActivityViewDisplayIdToParentMap.put(childDisplayId, info);
}
info.mMatrix.setValues(matrixValues);
if (mCurClient == null || mCurClient.curSession == null) {
return;
}
Matrix matrix = null;
int displayId = mCurClient.selfReportedDisplayId;
boolean needToNotify = false;
while (true) {
needToNotify |= (displayId == childDisplayId);
final ActivityViewInfo next = mActivityViewDisplayIdToParentMap.get(displayId);
if (next == null) {
break;
}
if (matrix == null) {
matrix = new Matrix(next.mMatrix);
} else {
matrix.postConcat(next.mMatrix);
}
if (next.mParentClient.selfReportedDisplayId == mCurTokenDisplayId) {
if (needToNotify) {
final float[] values = new float[9];
matrix.getValues(values);
try {
mCurClient.client.updateActivityViewToScreenMatrix(mCurSeq, values);
} catch (RemoteException e) {
}
// null matrixValues means that the entry needs to be removed.
if (matrixValues == null) {
final ActivityViewInfo info =
mActivityViewDisplayIdToParentMap.get(childDisplayId);
if (info == null) {
return;
}
break;
if (info.mParentClient != cs) {
throw new SecurityException("Only the owner client can clear"
+ " ActivityViewGeometry for display #" + childDisplayId);
}
mActivityViewDisplayIdToParentMap.remove(childDisplayId);
return;
}
ActivityViewInfo info = mActivityViewDisplayIdToParentMap.get(childDisplayId);
if (info != null && info.mParentClient != cs) {
throw new InvalidParameterException("Display #" + childDisplayId
+ " is already registered by " + info.mParentClient);
}
if (info == null) {
if (!mWindowManagerInternal.isUidAllowedOnDisplay(childDisplayId, cs.uid)) {
throw new SecurityException(cs + " cannot access to display #"
+ childDisplayId);
}
info = new ActivityViewInfo(cs, new Matrix());
mActivityViewDisplayIdToParentMap.put(childDisplayId, info);
}
info.mMatrix.setValues(matrixValues);
if (mCurClient == null || mCurClient.curSession == null) {
return;
}
Matrix matrix = null;
int displayId = mCurClient.selfReportedDisplayId;
boolean needToNotify = false;
while (true) {
needToNotify |= (displayId == childDisplayId);
final ActivityViewInfo next = mActivityViewDisplayIdToParentMap.get(displayId);
if (next == null) {
break;
}
if (matrix == null) {
matrix = new Matrix(next.mMatrix);
} else {
matrix.postConcat(next.mMatrix);
}
if (next.mParentClient.selfReportedDisplayId == mCurTokenDisplayId) {
if (needToNotify) {
final float[] values = new float[9];
matrix.getValues(values);
try {
mCurClient.client.updateActivityViewToScreenMatrix(mCurSeq, values);
} catch (RemoteException e) {
}
}
break;
}
displayId = info.mParentClient.selfReportedDisplayId;
}
displayId = info.mParentClient.selfReportedDisplayId;
}
}
});
}
@Override

View File

@@ -82,6 +82,7 @@ import com.android.internal.inputmethod.IIntResultCallback;
import com.android.internal.inputmethod.IMultiClientInputMethod;
import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.IMultiClientInputMethodSession;
import com.android.internal.inputmethod.IVoidResultCallback;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
@@ -1776,23 +1777,26 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
public void showInputMethodPickerFromClient(
IInputMethodClient client, int auxiliarySubtypeMode) {
public void showInputMethodPickerFromClient(IInputMethodClient client,
int auxiliarySubtypeMode, IVoidResultCallback resultCallback) {
reportNotSupported();
CallbackUtils.onResult(resultCallback, () -> { });
}
@BinderThread
@Override
public void showInputMethodPickerFromSystem(
IInputMethodClient client, int auxiliarySubtypeMode, int displayId) {
public void showInputMethodPickerFromSystem(IInputMethodClient client,
int auxiliarySubtypeMode, int displayId, IVoidResultCallback resultCallback) {
reportNotSupported();
CallbackUtils.onResult(resultCallback, () -> { });
}
@BinderThread
@Override
public void showInputMethodAndSubtypeEnablerFromClient(
IInputMethodClient client, String inputMethodId) {
public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient client,
String inputMethodId, IVoidResultCallback resultCallback) {
reportNotSupported();
CallbackUtils.onResult(resultCallback, () -> { });
}
@BinderThread
@@ -1825,8 +1829,9 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
public void reportActivityView(IInputMethodClient parentClient, int childDisplayId,
float[] matrixValues) {
float[] matrixValues, IVoidResultCallback resultCallback) {
reportNotSupported();
CallbackUtils.onResult(resultCallback, () -> { });
}
@BinderThread