From c4663ba6a98c93c305778af2d7770d3cfa7d345a Mon Sep 17 00:00:00 2001 From: Wilson Wu Date: Thu, 21 Jan 2021 18:51:27 +0800 Subject: [PATCH] Make IInputMethodManager to oneway (10/N) 1. Comply following methods to IVoidResultCallback to emulate current behavior. -. setAdditionalInputMethodSubtypes -. removeImeSurface -. removeImeSurfaceFromWindow 2. Add "oneway" to all methods which we already apply them to result-callback model. Bug: 163453493 Test: Manual test with keyboard Test: atest CtsInputMethodTestCases Test: atest DisplayImeControllerTest Change-Id: Icb396ae5d74060af69c4ecb16723b2e37b9f2067 --- .../view/inputmethod/InputMethodManager.java | 8 +- .../internal/view/IInputMethodManager.aidl | 44 ++++--- .../wm/shell/common/DisplayImeController.java | 6 +- .../common/DisplayImeControllerTest.java | 2 + .../InputMethodManagerService.java | 116 ++++++++++-------- .../MultiClientInputMethodManagerService.java | 11 +- 6 files changed, 107 insertions(+), 80 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 5140c09dc323d..90c8e17a69841 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -2307,7 +2307,9 @@ public final class InputMethodManager { public void removeImeSurface(IBinder windowToken) { synchronized (mH) { try { - mService.removeImeSurfaceFromWindow(windowToken); + final Completable.Void value = Completable.createVoid(); + mService.removeImeSurfaceFromWindow(windowToken, ResultCallbacks.of(value)); + Completable.getResult(value); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3239,7 +3241,9 @@ public final class InputMethodManager { @Deprecated public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { try { - mService.setAdditionalInputMethodSubtypes(imiId, subtypes); + final Completable.Void value = Completable.createVoid(); + mService.setAdditionalInputMethodSubtypes(imiId, subtypes, ResultCallbacks.of(value)); + Completable.getResult(value); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index b42404fb6d566..892c5a53527b7 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -41,22 +41,24 @@ interface IInputMethodManager { int untrustedDisplayId); // TODO: Use ParceledListSlice instead - void getInputMethodList(int userId, in IInputMethodInfoListResultCallback resultCallback); - // TODO: Use ParceledListSlice instead - void getEnabledInputMethodList(int userId, + oneway void getInputMethodList(int userId, in IInputMethodInfoListResultCallback resultCallback); - void getEnabledInputMethodSubtypeList(in String imiId, boolean allowsImplicitlySelectedSubtypes, + // TODO: Use ParceledListSlice instead + oneway void getEnabledInputMethodList(int userId, + in IInputMethodInfoListResultCallback resultCallback); + oneway void getEnabledInputMethodSubtypeList(in String imiId, + boolean allowsImplicitlySelectedSubtypes, in IInputMethodSubtypeListResultCallback resultCallback); - void getLastInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback); + oneway void getLastInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback); - void showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, + oneway void showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, in ResultReceiver resultReceiver, in IBooleanResultCallback resultCallback); - void hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, + oneway void hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, in ResultReceiver resultReceiver, in IBooleanResultCallback resultCallback); // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'attribute' is non-null then also does startInput. // @NonNull - void startInputOrWindowGainedFocus( + oneway void startInputOrWindowGainedFocus( /* @StartInputReason */ int startInputReason, in IInputMethodClient client, in IBinder windowToken, /* @StartInputFlags */ int startInputFlags, @@ -66,29 +68,31 @@ interface IInputMethodManager { int unverifiedTargetSdkVersion, in IInputBindResultResultCallback inputBindResult); - void showInputMethodPickerFromClient(in IInputMethodClient client, + oneway void showInputMethodPickerFromClient(in IInputMethodClient client, int auxiliarySubtypeMode, in IVoidResultCallback resultCallback); - void showInputMethodPickerFromSystem(in IInputMethodClient client, int auxiliarySubtypeMode, - int displayId, in IVoidResultCallback resultCallback); - void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId, + oneway void showInputMethodPickerFromSystem(in IInputMethodClient client, + int auxiliarySubtypeMode, int displayId, in IVoidResultCallback resultCallback); + oneway void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, + String topId, in IVoidResultCallback resultCallback); + oneway void isInputMethodPickerShownForTest(in IBooleanResultCallback resultCallback); + oneway void getCurrentInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback); + oneway void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes, in IVoidResultCallback resultCallback); - void isInputMethodPickerShownForTest(in IBooleanResultCallback resultCallback); - void getCurrentInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback); - void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); // This is kept due to @UnsupportedAppUsage. // TODO(Bug 113914148): Consider removing this. - void getInputMethodWindowVisibleHeight(IIntResultCallback resultCallback); + oneway void getInputMethodWindowVisibleHeight(IIntResultCallback resultCallback); - void reportActivityView(in IInputMethodClient parentClient, int childDisplayId, + oneway void reportActivityView(in IInputMethodClient parentClient, int childDisplayId, in float[] matrixValues, in IVoidResultCallback resultCallback); oneway void reportPerceptible(in IBinder windowToken, boolean perceptible); /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */ - void removeImeSurface(); + oneway void removeImeSurface(in IVoidResultCallback resultCallback); /** Remove the IME surface. Requires passing the currently focused window. */ - void removeImeSurfaceFromWindow(in IBinder windowToken); + oneway void removeImeSurfaceFromWindow(in IBinder windowToken, + in IVoidResultCallback resultCallback); void startProtoDump(in byte[] protoDump, int source, String where); - void isImeTraceEnabled(in IBooleanResultCallback resultCallback); + oneway void isImeTraceEnabled(in IBooleanResultCallback resultCallback); // Starts an ime trace. void startImeTrace(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java index 39441281f670a..9e1ea53c8f016 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java @@ -42,6 +42,8 @@ import android.view.animation.PathInterpolator; import androidx.annotation.BinderThread; import androidx.annotation.VisibleForTesting; +import com.android.internal.inputmethod.Completable; +import com.android.internal.inputmethod.ResultCallbacks; import com.android.internal.view.IInputMethodManager; import java.util.ArrayList; @@ -506,7 +508,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged try { // Remove the IME surface to make the insets invisible for // non-client controlled insets. - imms.removeImeSurface(); + final Completable.Void value = Completable.createVoid(); + imms.removeImeSurface(ResultCallbacks.of(value)); + Completable.getResult(value); } catch (RemoteException e) { Slog.e(TAG, "Failed to remove IME surface.", e); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java index 5e0d51809d442..47104ce6afc00 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java @@ -65,6 +65,8 @@ public class DisplayImeControllerTest { public IInputMethodManager getImms() { return mMock; } + @Override + void removeImeSurface() { } }.new PerDisplay(DEFAULT_DISPLAY, ROTATION_0); } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 143ec157119e6..6308ace260110 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3947,58 +3947,61 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { - // By this IPC call, only a process which shares the same uid with the IME can add - // additional input method subtypes to the IME. - if (TextUtils.isEmpty(imiId) || subtypes == null) return; - final ArrayList toBeAdded = new ArrayList<>(); - for (InputMethodSubtype subtype : subtypes) { - if (!toBeAdded.contains(subtype)) { - toBeAdded.add(subtype); - } else { - Slog.w(TAG, "Duplicated subtype definition found: " - + subtype.getLocale() + ", " + subtype.getMode()); + public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes, + IVoidResultCallback resultCallback) { + CallbackUtils.onResult(resultCallback, () -> { + // By this IPC call, only a process which shares the same uid with the IME can add + // additional input method subtypes to the IME. + if (TextUtils.isEmpty(imiId) || subtypes == null) return; + final ArrayList toBeAdded = new ArrayList<>(); + for (InputMethodSubtype subtype : subtypes) { + if (!toBeAdded.contains(subtype)) { + toBeAdded.add(subtype); + } else { + Slog.w(TAG, "Duplicated subtype definition found: " + + subtype.getLocale() + ", " + subtype.getMode()); + } } - } - synchronized (mMethodMap) { - if (!calledFromValidUserLocked()) { - return; - } - if (!mSystemReady) { - return; - } - final InputMethodInfo imi = mMethodMap.get(imiId); - if (imi == null) return; - final String[] packageInfos; - try { - packageInfos = mIPackageManager.getPackagesForUid(Binder.getCallingUid()); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to get package infos"); - return; - } - if (packageInfos != null) { - final int packageNum = packageInfos.length; - for (int i = 0; i < packageNum; ++i) { - if (packageInfos[i].equals(imi.getPackageName())) { - if (subtypes.length > 0) { - mAdditionalSubtypeMap.put(imi.getId(), toBeAdded); - } else { - mAdditionalSubtypeMap.remove(imi.getId()); + synchronized (mMethodMap) { + if (!calledFromValidUserLocked()) { + return; + } + if (!mSystemReady) { + return; + } + final InputMethodInfo imi = mMethodMap.get(imiId); + if (imi == null) return; + final String[] packageInfos; + try { + packageInfos = mIPackageManager.getPackagesForUid(Binder.getCallingUid()); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get package infos"); + return; + } + if (packageInfos != null) { + final int packageNum = packageInfos.length; + for (int i = 0; i < packageNum; ++i) { + if (packageInfos[i].equals(imi.getPackageName())) { + if (subtypes.length > 0) { + mAdditionalSubtypeMap.put(imi.getId(), toBeAdded); + } else { + mAdditionalSubtypeMap.remove(imi.getId()); + } + AdditionalSubtypeUtils.save(mAdditionalSubtypeMap, mMethodMap, + mSettings.getCurrentUserId()); + final long ident = Binder.clearCallingIdentity(); + try { + buildInputMethodListLocked(false /* resetDefaultEnabledIme */); + } finally { + Binder.restoreCallingIdentity(ident); + } + return; } - AdditionalSubtypeUtils.save(mAdditionalSubtypeMap, mMethodMap, - mSettings.getCurrentUserId()); - final long ident = Binder.clearCallingIdentity(); - try { - buildInputMethodListLocked(false /* resetDefaultEnabledIme */); - } finally { - Binder.restoreCallingIdentity(ident); - } - return; } } } - } - return; + return; + }); } /** @@ -4103,16 +4106,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void removeImeSurface() { - mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null); - mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); + public void removeImeSurface(IVoidResultCallback resultCallback) { + CallbackUtils.onResult(resultCallback, () -> { + mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null); + mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); + }); } @Override - public void removeImeSurfaceFromWindow(IBinder windowToken) { - // No permission check, because we'll only execute the request if the calling window is - // also the current IME client. - mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE_FROM_WINDOW, windowToken).sendToTarget(); + public void removeImeSurfaceFromWindow(IBinder windowToken, + IVoidResultCallback resultCallback) { + CallbackUtils.onResult(resultCallback, () -> { + // No permission check, because we'll only execute the request if the calling window is + // also the current IME client. + mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE_FROM_WINDOW, windowToken).sendToTarget(); + }); } /** diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 2dd7096cf763c..7f9c76634422d 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1502,14 +1502,17 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void removeImeSurface() { + public void removeImeSurface(IVoidResultCallback resultCallback) { reportNotSupported(); + CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @Override - public void removeImeSurfaceFromWindow(IBinder windowToken) { + public void removeImeSurfaceFromWindow(IBinder windowToken, + IVoidResultCallback resultCallback) { reportNotSupported(); + CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @@ -1815,8 +1818,10 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { + public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes, + IVoidResultCallback resultCallback) { reportNotSupported(); + CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread