From 9dde7014461bd175fd437a6376f8fc10d8570b65 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 1 Jul 2021 21:26:52 -0700 Subject: [PATCH] Switch back to sync IInputMethodManager This CL logically reverts recent CLs [1][2][3][4][5][6][7][8][9] to switch back to the previous sync IPC approach in IInputMethodManager except for the following two IPCs. * reportPerceptibleAsync * removeImeSurfaceFromWindowAsync Reason for revert: We need more time to understand its performance implications. [1]: If4b40244a2e0e3b11c38c1da9340ba8e5166ad64 b9590fa1e11af459a5ebc15e0536ff2e755ddbcf [2]: If79e063641a01b325c63eb9f871f5b992d7c0b72 5a5648dcb5a362647e79cca79bcc846752c26551 [3]: I1547b98b2aacf764e33aadc9ab784f2013f58f2f d833f0dab4406a72bdcc24aa041358f2eb99f03b [4]: I646ef4ae0570aae1812ea267f309441fdec6938d 38fd020616722be4e28bfd9797f73cc768cddd72 [5]: Iaa63e01453da4ff0e3f446eac036b3be3180cb73 4a820ccc41045d7f92c47d1c49e4c34398f589e8 [6]: Id516fd1c961f43ac3e139c88d7ed004c188d458b 0a32fd21efca72f4bfcdd1e6bf21a06e1d9146e0 [7]: Icb396ae5d74060af69c4ecb16723b2e37b9f2067 c4663ba6a98c93c305778af2d7770d3cfa7d345a [8]: I3eafbc28ed3acf3ba859885bf201cb06b3149b94 f226a79fee58d55ae2dbdc5049479146e421ce93 [9]: Ic584203c1221fbae17f5e2d8f09e3992df061646 5e2d9f271d1f24fc946661579628fb9a817143dc Bug: 163453493 Bug: 174892351 Fix: 190486491 Test: atest CtsInputMethodTestCases Change-Id: If16ac0de536d9089eb04f6e07b1ee47378124658 Merged-In: If16ac0de536d9089eb04f6e07b1ee47378124658 --- .../android/util/imetracing/ImeTracing.java | 6 +- .../util/imetracing/ImeTracingClientImpl.java | 7 +- .../view/inputmethod/InputMethodManager.java | 138 +--- .../internal/view/IInputMethodManager.aidl | 70 +- .../wm/shell/common/DisplayImeController.java | 6 +- .../InputMethodManagerService.java | 704 ++++++++---------- .../MultiClientInputMethodManagerService.java | 141 +--- 7 files changed, 417 insertions(+), 655 deletions(-) diff --git a/core/java/android/util/imetracing/ImeTracing.java b/core/java/android/util/imetracing/ImeTracing.java index 2fcaec91833d6..4696ae325e7bc 100644 --- a/core/java/android/util/imetracing/ImeTracing.java +++ b/core/java/android/util/imetracing/ImeTracing.java @@ -27,8 +27,6 @@ import android.util.Log; import android.util.proto.ProtoOutputStream; import android.view.inputmethod.InputMethodManager; -import com.android.internal.inputmethod.Completable; -import com.android.internal.inputmethod.ResultCallbacks; import com.android.internal.view.IInputMethodManager; import java.io.PrintWriter; @@ -92,9 +90,7 @@ public abstract class ImeTracing { * @param where */ public void sendToService(byte[] protoDump, int source, String where) throws RemoteException { - final Completable.Void value = Completable.createVoid(); - mService.startProtoDump(protoDump, source, where, ResultCallbacks.of(value)); - Completable.getResult(value); + mService.startProtoDump(protoDump, source, where); } /** diff --git a/core/java/android/util/imetracing/ImeTracingClientImpl.java b/core/java/android/util/imetracing/ImeTracingClientImpl.java index 17cdc46876601..5a57a6ade98b7 100644 --- a/core/java/android/util/imetracing/ImeTracingClientImpl.java +++ b/core/java/android/util/imetracing/ImeTracingClientImpl.java @@ -24,9 +24,6 @@ import android.util.Log; import android.util.proto.ProtoOutputStream; import android.view.inputmethod.InputMethodManager; -import com.android.internal.inputmethod.Completable; -import com.android.internal.inputmethod.ResultCallbacks; - import java.io.PrintWriter; /** @@ -34,9 +31,7 @@ import java.io.PrintWriter; */ class ImeTracingClientImpl extends ImeTracing { ImeTracingClientImpl() throws ServiceNotFoundException, RemoteException { - final Completable.Boolean value = Completable.createBoolean(); - mService.isImeTraceEnabled(ResultCallbacks.of(value)); - sEnabled = Completable.getResult(value); + sEnabled = mService.isImeTraceEnabled(); } @Override diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index b572d0871f125..42d77cd096893 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -88,10 +88,8 @@ import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.autofill.AutofillManager; import com.android.internal.annotations.GuardedBy; -import com.android.internal.inputmethod.Completable; import com.android.internal.inputmethod.InputMethodDebug; import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry; -import com.android.internal.inputmethod.ResultCallbacks; import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.internal.inputmethod.StartInputFlags; import com.android.internal.inputmethod.StartInputReason; @@ -265,14 +263,6 @@ public final class InputMethodManager { private static final int NOT_A_SUBTYPE_ID = -1; - /** - * {@code true} to try to avoid blocking apps' UI thread by sending - * {@link StartInputReason#WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION} and - * {@link StartInputReason#WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION} in a truly asynchronous - * way. {@code false} to go back to the previous synchronous semantics. - */ - private static final boolean USE_REPORT_WINDOW_GAINED_FOCUS_ASYNC = true; - /** * A constant that represents Voice IME. * @@ -686,28 +676,18 @@ public final class InputMethodManager { + ", nextFocusIsServedView=" + nextFocusHasConnection); } - if (USE_REPORT_WINDOW_GAINED_FOCUS_ASYNC) { - mService.reportWindowGainedFocusAsync( - nextFocusHasConnection, mClient, focusedView.getWindowToken(), - startInputFlags, softInputMode, windowFlags, - mCurRootView.mContext.getApplicationInfo().targetSdkVersion); - } else { - final int startInputReason = nextFocusHasConnection - ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION - : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; - final Completable.InputBindResult value = - Completable.createInputBindResult(); - mService.startInputOrWindowGainedFocus( - startInputReason, mClient, - focusedView.getWindowToken(), startInputFlags, softInputMode, - windowFlags, - null, - null, - 0 /* missingMethodFlags */, - mCurRootView.mContext.getApplicationInfo().targetSdkVersion, - ResultCallbacks.of(value)); - Completable.getResult(value); // ignore the result - } + final int startInputReason = nextFocusHasConnection + ? WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION + : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; + // ignore the result + mService.startInputOrWindowGainedFocus( + startInputReason, mClient, + focusedView.getWindowToken(), startInputFlags, softInputMode, + windowFlags, + null, + null, + 0 /* missingMethodFlags */, + mCurRootView.mContext.getApplicationInfo().targetSdkVersion); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1249,9 +1229,7 @@ public final class InputMethodManager { // We intentionally do not use UserHandle.getCallingUserId() here because for system // services InputMethodManagerInternal.getInputMethodListAsUser() should be used // instead. - final Completable.InputMethodInfoList value = Completable.createInputMethodInfoList(); - mService.getInputMethodList(UserHandle.myUserId(), ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.getInputMethodList(UserHandle.myUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1269,9 +1247,7 @@ public final class InputMethodManager { @NonNull public List getInputMethodListAsUser(@UserIdInt int userId) { try { - final Completable.InputMethodInfoList value = Completable.createInputMethodInfoList(); - mService.getInputMethodList(userId, ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.getInputMethodList(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1289,9 +1265,7 @@ public final class InputMethodManager { // We intentionally do not use UserHandle.getCallingUserId() here because for system // services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used // instead. - final Completable.InputMethodInfoList value = Completable.createInputMethodInfoList(); - mService.getEnabledInputMethodList(UserHandle.myUserId(), ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.getEnabledInputMethodList(UserHandle.myUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1307,9 +1281,7 @@ public final class InputMethodManager { @RequiresPermission(INTERACT_ACROSS_USERS_FULL) public List getEnabledInputMethodListAsUser(@UserIdInt int userId) { try { - final Completable.InputMethodInfoList value = Completable.createInputMethodInfoList(); - mService.getEnabledInputMethodList(userId, ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.getEnabledInputMethodList(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1328,13 +1300,9 @@ public final class InputMethodManager { public List getEnabledInputMethodSubtypeList(InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) { try { - final Completable.InputMethodSubtypeList value = - Completable.createInputMethodSubtypeList(); - mService.getEnabledInputMethodSubtypeList( + return mService.getEnabledInputMethodSubtypeList( imi == null ? null : imi.getId(), - allowsImplicitlySelectedSubtypes, - ResultCallbacks.of(value)); - return Completable.getResult(value); + allowsImplicitlySelectedSubtypes); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1669,15 +1637,12 @@ public final class InputMethodManager { try { Log.d(TAG, "showSoftInput() view=" + view + " flags=" + flags + " reason=" + InputMethodDebug.softInputDisplayReasonToString(reason)); - final Completable.Boolean value = Completable.createBoolean(); - mService.showSoftInput( + return mService.showSoftInput( mClient, view.getWindowToken(), flags, resultReceiver, - reason, - ResultCallbacks.of(value)); - return Completable.getResult(value); + reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1704,15 +1669,12 @@ public final class InputMethodManager { Log.w(TAG, "No current root view, ignoring showSoftInputUnchecked()"); return; } - final Completable.Boolean value = Completable.createBoolean(); mService.showSoftInput( mClient, mCurRootView.getView().getWindowToken(), flags, resultReceiver, - SoftInputShowHideReason.SHOW_SOFT_INPUT, - ResultCallbacks.of(value)); - Completable.getResult(value); // ignore the result + SoftInputShowHideReason.SHOW_SOFT_INPUT); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1791,10 +1753,7 @@ public final class InputMethodManager { } try { - final Completable.Boolean value = Completable.createBoolean(); - mService.hideSoftInput(mClient, windowToken, flags, resultReceiver, reason, - ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.hideSoftInput(mClient, windowToken, flags, resultReceiver, reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2030,13 +1989,10 @@ public final class InputMethodManager { + InputMethodDebug.startInputFlagsToString(startInputFlags)); } try { - final Completable.InputBindResult value = Completable.createInputBindResult(); - mService.startInputOrWindowGainedFocus( + res = mService.startInputOrWindowGainedFocus( startInputReason, mClient, windowGainingFocus, startInputFlags, softInputMode, windowFlags, tba, servedContext, missingMethodFlags, - view.getContext().getApplicationInfo().targetSdkVersion, - ResultCallbacks.of(value)); - res = Completable.getResult(value); + view.getContext().getApplicationInfo().targetSdkVersion); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2144,15 +2100,12 @@ public final class InputMethodManager { return; } try { - final Completable.Boolean value = Completable.createBoolean(); mService.hideSoftInput( mClient, mCurRootView.getView().getWindowToken(), HIDE_NOT_ALWAYS, null, - SoftInputShowHideReason.HIDE_SOFT_INPUT, - ResultCallbacks.of(value)); - Completable.getResult(value); // ignore the result + SoftInputShowHideReason.HIDE_SOFT_INPUT); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2832,10 +2785,7 @@ public final class InputMethodManager { ? SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES : SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES; try { - final Completable.Void value = Completable.createVoid(); - mService.showInputMethodPickerFromSystem( - mClient, mode, displayId, ResultCallbacks.of(value)); - Completable.getResult(value); + mService.showInputMethodPickerFromSystem(mClient, mode, displayId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2843,10 +2793,7 @@ public final class InputMethodManager { private void showInputMethodPickerLocked() { try { - final Completable.Void value = Completable.createVoid(); - mService.showInputMethodPickerFromClient( - mClient, SHOW_IM_PICKER_MODE_AUTO, ResultCallbacks.of(value)); - Completable.getResult(value); + mService.showInputMethodPickerFromClient(mClient, SHOW_IM_PICKER_MODE_AUTO); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2866,9 +2813,7 @@ public final class InputMethodManager { @TestApi public boolean isInputMethodPickerShown() { try { - final Completable.Boolean value = Completable.createBoolean(); - mService.isInputMethodPickerShownForTest(ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.isInputMethodPickerShownForTest(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2882,10 +2827,7 @@ public final class InputMethodManager { */ public void showInputMethodAndSubtypeEnabler(String imiId) { try { - final Completable.Void value = Completable.createVoid(); - mService.showInputMethodAndSubtypeEnablerFromClient( - mClient, imiId, ResultCallbacks.of(value)); - Completable.getResult(value); + mService.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2898,9 +2840,7 @@ public final class InputMethodManager { */ public InputMethodSubtype getCurrentInputMethodSubtype() { try { - final Completable.InputMethodSubtype value = Completable.createInputMethodSubtype(); - mService.getCurrentInputMethodSubtype(ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.getCurrentInputMethodSubtype(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2949,11 +2889,7 @@ public final class InputMethodManager { } final List enabledSubtypes; try { - final Completable.InputMethodSubtypeList value = - Completable.createInputMethodSubtypeList(); - mService.getEnabledInputMethodSubtypeList( - imeId, true, ResultCallbacks.of(value)); - enabledSubtypes = Completable.getResult(value); + enabledSubtypes = mService.getEnabledInputMethodSubtypeList(imeId, true); } catch (RemoteException e) { return false; } @@ -3021,9 +2957,7 @@ public final class InputMethodManager { @UnsupportedAppUsage public int getInputMethodWindowVisibleHeight() { try { - final Completable.Int value = Completable.createInt(); - mService.getInputMethodWindowVisibleHeight(ResultCallbacks.of(value)); - return Completable.getIntResult(value); + return mService.getInputMethodWindowVisibleHeight(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3118,9 +3052,7 @@ public final class InputMethodManager { @Deprecated public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { try { - final Completable.Void value = Completable.createVoid(); - mService.setAdditionalInputMethodSubtypes(imiId, subtypes, ResultCallbacks.of(value)); - Completable.getResult(value); + mService.setAdditionalInputMethodSubtypes(imiId, subtypes); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3128,9 +3060,7 @@ public final class InputMethodManager { public InputMethodSubtype getLastInputMethodSubtype() { try { - final Completable.InputMethodSubtype value = Completable.createInputMethodSubtype(); - mService.getLastInputMethodSubtype(ResultCallbacks.of(value)); - return Completable.getResult(value); + return mService.getLastInputMethodSubtype(); } 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 4891ce97f05dc..d40c064c62e69 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -24,13 +24,6 @@ import android.view.inputmethod.EditorInfo; import com.android.internal.view.InputBindResult; 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.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 @@ -41,64 +34,51 @@ interface IInputMethodManager { int untrustedDisplayId); // TODO: Use ParceledListSlice instead - oneway void getInputMethodList(int userId, - in IInputMethodInfoListResultCallback resultCallback); + List getInputMethodList(int userId); // TODO: Use ParceledListSlice instead - oneway void getEnabledInputMethodList(int userId, - in IInputMethodInfoListResultCallback resultCallback); - oneway void getEnabledInputMethodSubtypeList(in String imiId, - boolean allowsImplicitlySelectedSubtypes, - in IInputMethodSubtypeListResultCallback resultCallback); - oneway void getLastInputMethodSubtype(in IInputMethodSubtypeResultCallback resultCallback); + List getEnabledInputMethodList(int userId); + List getEnabledInputMethodSubtypeList(in String imiId, + boolean allowsImplicitlySelectedSubtypes); + InputMethodSubtype getLastInputMethodSubtype(); - oneway void showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, - in ResultReceiver resultReceiver, int reason, in IBooleanResultCallback resultCallback); - oneway void hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, - in ResultReceiver resultReceiver, int reason, in IBooleanResultCallback resultCallback); + boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, + in ResultReceiver resultReceiver, int reason); + boolean hideSoftInput(in IInputMethodClient client, IBinder windowToken, int flags, + in ResultReceiver resultReceiver, int reason); // 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 - oneway void startInputOrWindowGainedFocus( + InputBindResult startInputOrWindowGainedFocus( /* @StartInputReason */ int startInputReason, in IInputMethodClient client, in IBinder windowToken, /* @StartInputFlags */ int startInputFlags, /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode, int windowFlags, in EditorInfo attribute, IInputContext inputContext, /* @InputConnectionInspector.MissingMethodFlags */ int missingMethodFlags, - int unverifiedTargetSdkVersion, - in IInputBindResultResultCallback inputBindResult); + int unverifiedTargetSdkVersion); - oneway void reportWindowGainedFocusAsync( - boolean nextFocusHasConnection, in IInputMethodClient client, in IBinder windowToken, - /* @StartInputFlags */ int startInputFlags, - /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode, - int windowFlags, int unverifiedTargetSdkVersion); - - oneway void showInputMethodPickerFromClient(in IInputMethodClient client, - int auxiliarySubtypeMode, in IVoidResultCallback resultCallback); - 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 showInputMethodPickerFromClient(in IInputMethodClient client, + int auxiliarySubtypeMode); + void showInputMethodPickerFromSystem(in IInputMethodClient client, + int auxiliarySubtypeMode, int displayId); + void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId); + boolean isInputMethodPickerShownForTest(); + InputMethodSubtype getCurrentInputMethodSubtype(); + void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); // This is kept due to @UnsupportedAppUsage. // TODO(Bug 113914148): Consider removing this. - oneway void getInputMethodWindowVisibleHeight(IIntResultCallback resultCallback); + int getInputMethodWindowVisibleHeight(); oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible); /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */ - oneway void removeImeSurface(in IVoidResultCallback resultCallback); + void removeImeSurface(); /** Remove the IME surface. Requires passing the currently focused window. */ oneway void removeImeSurfaceFromWindowAsync(in IBinder windowToken); - oneway void startProtoDump(in byte[] protoDump, int source, String where, - in IVoidResultCallback resultCallback); - oneway void isImeTraceEnabled(in IBooleanResultCallback resultCallback); + void startProtoDump(in byte[] protoDump, int source, String where); + boolean isImeTraceEnabled(); // Starts an ime trace. - oneway void startImeTrace(in IVoidResultCallback resultCallback); + void startImeTrace(); // Stops an ime trace. - oneway void stopImeTrace(in IVoidResultCallback resultCallback); + void stopImeTrace(); } 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 f565724813ebf..a7996f056785b 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,8 +42,6 @@ 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; @@ -540,9 +538,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged try { // Remove the IME surface to make the insets invisible for // non-client controlled insets. - final Completable.Void value = Completable.createVoid(); - imms.removeImeSurface(ResultCallbacks.of(value)); - Completable.getResult(value); + imms.removeImeSurface(); } catch (RemoteException e) { Slog.e(TAG, "Failed to remove IME surface.", e); } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 457c94e25597a..fd0f1c38938fc 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -157,13 +157,8 @@ 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; 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; @@ -213,7 +208,6 @@ import java.util.Objects; import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; /** * This class provides a system service that manages input methods. @@ -1895,51 +1889,45 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void getInputMethodList(@UserIdInt int userId, - IInputMethodInfoListResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - if (UserHandle.getCallingUserId() != userId) { - mContext.enforceCallingPermission( - Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + public List getInputMethodList(@UserIdInt int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + } + synchronized (mMethodMap) { + final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId, + mSettings.getCurrentUserId(), null); + if (resolvedUserIds.length != 1) { + return Collections.emptyList(); } - synchronized (mMethodMap) { - final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId, - mSettings.getCurrentUserId(), null); - if (resolvedUserIds.length != 1) { - return Collections.emptyList(); - } - final long ident = Binder.clearCallingIdentity(); - try { - return getInputMethodListLocked(resolvedUserIds[0]); - } finally { - Binder.restoreCallingIdentity(ident); - } + final long ident = Binder.clearCallingIdentity(); + try { + return getInputMethodListLocked(resolvedUserIds[0]); + } finally { + Binder.restoreCallingIdentity(ident); } - }); + } } @Override - public void getEnabledInputMethodList(@UserIdInt int userId, - IInputMethodInfoListResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - if (UserHandle.getCallingUserId() != userId) { - mContext.enforceCallingPermission( - Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + public List getEnabledInputMethodList(@UserIdInt int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + } + synchronized (mMethodMap) { + final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId, + mSettings.getCurrentUserId(), null); + if (resolvedUserIds.length != 1) { + return Collections.emptyList(); } - synchronized (mMethodMap) { - final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId, - mSettings.getCurrentUserId(), null); - if (resolvedUserIds.length != 1) { - return Collections.emptyList(); - } - final long ident = Binder.clearCallingIdentity(); - try { - return getEnabledInputMethodListLocked(resolvedUserIds[0]); - } finally { - Binder.restoreCallingIdentity(ident); - } + final long ident = Binder.clearCallingIdentity(); + try { + return getEnabledInputMethodListLocked(resolvedUserIds[0]); + } finally { + Binder.restoreCallingIdentity(ident); } - }); + } } @GuardedBy("mMethodMap") @@ -2097,29 +2085,25 @@ public class InputMethodManagerService extends IInputMethodManager.Stub * @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 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); - } + public List 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(); } - }); + final long ident = Binder.clearCallingIdentity(); + try { + return getEnabledInputMethodSubtypeListLocked(imiId, + allowsImplicitlySelectedSubtypes, resolvedUserIds[0]); + } finally { + Binder.restoreCallingIdentity(ident); + } + } } @GuardedBy("mMethodMap") @@ -3067,44 +3051,41 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void showSoftInput(IInputMethodClient client, IBinder windowToken, int flags, - ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, - IBooleanResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput"); - int uid = Binder.getCallingUid(); - ImeTracing.getInstance().triggerManagerServiceDump( - "InputMethodManagerService#showSoftInput"); - synchronized (mMethodMap) { - if (!calledFromValidUserLocked()) { - return false; - } - final long ident = Binder.clearCallingIdentity(); - try { - if (mCurClient == null || client == null - || mCurClient.client.asBinder() != client.asBinder()) { - // We need to check if this is the current client with - // focus in the window manager, to allow this call to - // be made before input is started in it. - final ClientState cs = mClients.get(client.asBinder()); - if (cs == null) { - throw new IllegalArgumentException( - "unknown client " + client.asBinder()); - } - if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid, - cs.selfReportedDisplayId)) { - Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client); - return false; - } - } - if (DEBUG) Slog.v(TAG, "Client requesting input be shown"); - return showCurrentInputLocked(windowToken, flags, resultReceiver, reason); - } finally { - Binder.restoreCallingIdentity(ident); - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } + public boolean showSoftInput(IInputMethodClient client, IBinder windowToken, int flags, + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput"); + int uid = Binder.getCallingUid(); + ImeTracing.getInstance().triggerManagerServiceDump( + "InputMethodManagerService#showSoftInput"); + synchronized (mMethodMap) { + if (!calledFromValidUserLocked()) { + return false; } - }); + final long ident = Binder.clearCallingIdentity(); + try { + if (mCurClient == null || client == null + || mCurClient.client.asBinder() != client.asBinder()) { + // We need to check if this is the current client with + // focus in the window manager, to allow this call to + // be made before input is started in it. + final ClientState cs = mClients.get(client.asBinder()); + if (cs == null) { + throw new IllegalArgumentException( + "unknown client " + client.asBinder()); + } + if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid, + cs.selfReportedDisplayId)) { + Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client); + return false; + } + } + if (DEBUG) Slog.v(TAG, "Client requesting input be shown"); + return showCurrentInputLocked(windowToken, flags, resultReceiver, reason); + } finally { + Binder.restoreCallingIdentity(ident); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } } @BinderThread @@ -3186,49 +3167,46 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void hideSoftInput(IInputMethodClient client, IBinder windowToken, int flags, - ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, - IBooleanResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - int uid = Binder.getCallingUid(); - ImeTracing.getInstance().triggerManagerServiceDump( - "InputMethodManagerService#hideSoftInput"); - synchronized (mMethodMap) { - if (!InputMethodManagerService.this.calledFromValidUserLocked()) { - return false; - } - final long ident = Binder.clearCallingIdentity(); - try { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput"); - if (mCurClient == null || client == null - || mCurClient.client.asBinder() != client.asBinder()) { - // We need to check if this is the current client with - // focus in the window manager, to allow this call to - // be made before input is started in it. - final ClientState cs = mClients.get(client.asBinder()); - if (cs == null) { - throw new IllegalArgumentException( - "unknown client " + client.asBinder()); - } - if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid, - cs.selfReportedDisplayId)) { - if (DEBUG) { - Slog.w(TAG, - "Ignoring hideSoftInput of uid " + uid + ": " + client); - } - return false; - } - } - - if (DEBUG) Slog.v(TAG, "Client requesting input be hidden"); - return InputMethodManagerService.this.hideCurrentInputLocked(windowToken, - flags, resultReceiver, reason); - } finally { - Binder.restoreCallingIdentity(ident); - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } + public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken, int flags, + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + int uid = Binder.getCallingUid(); + ImeTracing.getInstance().triggerManagerServiceDump( + "InputMethodManagerService#hideSoftInput"); + synchronized (mMethodMap) { + if (!InputMethodManagerService.this.calledFromValidUserLocked()) { + return false; } - }); + final long ident = Binder.clearCallingIdentity(); + try { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput"); + if (mCurClient == null || client == null + || mCurClient.client.asBinder() != client.asBinder()) { + // We need to check if this is the current client with + // focus in the window manager, to allow this call to + // be made before input is started in it. + final ClientState cs = mClients.get(client.asBinder()); + if (cs == null) { + throw new IllegalArgumentException( + "unknown client " + client.asBinder()); + } + if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid, + cs.selfReportedDisplayId)) { + if (DEBUG) { + Slog.w(TAG, + "Ignoring hideSoftInput of uid " + uid + ": " + client); + } + return false; + } + } + + if (DEBUG) Slog.v(TAG, "Client requesting input be hidden"); + return InputMethodManagerService.this.hideCurrentInputLocked(windowToken, + flags, resultReceiver, reason); + } finally { + Binder.restoreCallingIdentity(ident); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } } boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver, @@ -3280,38 +3258,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @NonNull @Override - public void reportWindowGainedFocusAsync( - boolean nextFocusHasConnection, IInputMethodClient client, IBinder windowToken, - @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode, - int windowFlags, int unverifiedTargetSdkVersion) { - final int startInputReason = nextFocusHasConnection - ? StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION - : StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; - try { - startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken, - startInputFlags, softInputMode, windowFlags, null /* attribute */, - null /* inputContext */, 0 /* missingMethods */, unverifiedTargetSdkVersion); - } catch (Throwable t) { - if (client != null) { - try { - client.throwExceptionFromSystem(t.getMessage()); - } catch (RemoteException ignore) { } - } - } - } - - @NonNull - @Override - public void startInputOrWindowGainedFocus( + public InputBindResult startInputOrWindowGainedFocus( @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken, @StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode, int windowFlags, @Nullable EditorInfo attribute, IInputContext inputContext, - @MissingMethodFlags int missingMethods, int unverifiedTargetSdkVersion, - IInputBindResultResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, (Supplier) () -> - startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken, + @MissingMethodFlags int missingMethods, int unverifiedTargetSdkVersion) { + return startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken, startInputFlags, softInputMode, windowFlags, attribute, inputContext, - missingMethods, unverifiedTargetSdkVersion)); + missingMethods, unverifiedTargetSdkVersion); } @NonNull @@ -3671,54 +3625,47 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - 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)); + 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; + } + + // 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, 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)); - }); + 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)); } /** * A test API for CTS to make sure that the input method menu is showing. - * - * @param resultCallback {@code true} while the input method menu is showing UI. */ - public void isInputMethodPickerShownForTest(IBooleanResultCallback resultCallback) { + public boolean isInputMethodPickerShownForTest() { synchronized(mMethodMap) { - CallbackUtils.onResult( - resultCallback, mMenuController::isisInputMethodPickerShownForTestLocked); + return mMenuController.isisInputMethodPickerShownForTestLocked(); } } @@ -3751,17 +3698,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @Override public void showInputMethodAndSubtypeEnablerFromClient( - 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)); + IInputMethodClient client, String inputMethodId) { + synchronized (mMethodMap) { + // TODO(yukawa): Should we verify the display ID? + if (!calledFromValidUserLocked()) { + return; } - }); + executeOrSendMessage(mCurMethod, mCaller.obtainMessageO( + MSG_SHOW_IM_SUBTYPE_ENABLER, inputMethodId)); + } } @BinderThread @@ -3869,89 +3814,83 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void getLastInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - synchronized (mMethodMap) { - if (!calledFromValidUserLocked()) { - return null; - } - final Pair 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; - } + public InputMethodSubtype getLastInputMethodSubtype() { + synchronized (mMethodMap) { + if (!calledFromValidUserLocked()) { + return null; } - }); + final Pair 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; + } + } } @Override - 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()); - } + 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()); } - 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; + } + 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; } } } - return; - }); + } } /** @@ -3963,19 +3902,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub * @return {@link WindowManagerInternal#getInputMethodWindowVisibleHeight(int)} */ @Override - public void getInputMethodWindowVisibleHeight(IIntResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - // TODO(yukawa): Should we verify the display ID? - return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId); - }); + public int getInputMethodWindowVisibleHeight() { + // TODO(yukawa): Should we verify the display ID? + return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId); } @Override - public void removeImeSurface(IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null); - mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); - }); + public void removeImeSurface() { + mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null); + mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); } @Override @@ -3992,100 +3927,93 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ @BinderThread @Override - public void startProtoDump(byte[] protoDump, int source, String where, - IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - if (protoDump == null && source != IME_TRACING_FROM_IMMS) { - // Dump not triggered from IMMS, but no proto information provided. - return; - } - ImeTracing tracingInstance = ImeTracing.getInstance(); - if (!tracingInstance.isAvailable() || !tracingInstance.isEnabled()) { - return; - } + public void startProtoDump(byte[] protoDump, int source, String where) { + if (protoDump == null && source != IME_TRACING_FROM_IMMS) { + // Dump not triggered from IMMS, but no proto information provided. + return; + } + ImeTracing tracingInstance = ImeTracing.getInstance(); + if (!tracingInstance.isAvailable() || !tracingInstance.isEnabled()) { + return; + } - ProtoOutputStream proto = new ProtoOutputStream(); - switch (source) { - case ImeTracing.IME_TRACING_FROM_CLIENT: - final long client_token = proto.start(InputMethodClientsTraceFileProto.ENTRY); - proto.write(InputMethodClientsTraceProto.ELAPSED_REALTIME_NANOS, - SystemClock.elapsedRealtimeNanos()); - proto.write(InputMethodClientsTraceProto.WHERE, where); - proto.write(InputMethodClientsTraceProto.CLIENT, protoDump); - proto.end(client_token); - break; - case ImeTracing.IME_TRACING_FROM_IMS: - final long service_token = proto.start(InputMethodServiceTraceFileProto.ENTRY); - proto.write(InputMethodServiceTraceProto.ELAPSED_REALTIME_NANOS, - SystemClock.elapsedRealtimeNanos()); - proto.write(InputMethodServiceTraceProto.WHERE, where); - proto.write(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE, protoDump); - proto.end(service_token); - break; - case IME_TRACING_FROM_IMMS: - final long managerservice_token = - proto.start(InputMethodManagerServiceTraceFileProto.ENTRY); - proto.write(InputMethodManagerServiceTraceProto.ELAPSED_REALTIME_NANOS, - SystemClock.elapsedRealtimeNanos()); - proto.write(InputMethodManagerServiceTraceProto.WHERE, where); - dumpDebug(proto, - InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE); - proto.end(managerservice_token); - break; - default: - // Dump triggered by a source not recognised. - return; - } - tracingInstance.addToBuffer(proto, source); - }); + ProtoOutputStream proto = new ProtoOutputStream(); + switch (source) { + case ImeTracing.IME_TRACING_FROM_CLIENT: + final long client_token = proto.start(InputMethodClientsTraceFileProto.ENTRY); + proto.write(InputMethodClientsTraceProto.ELAPSED_REALTIME_NANOS, + SystemClock.elapsedRealtimeNanos()); + proto.write(InputMethodClientsTraceProto.WHERE, where); + proto.write(InputMethodClientsTraceProto.CLIENT, protoDump); + proto.end(client_token); + break; + case ImeTracing.IME_TRACING_FROM_IMS: + final long service_token = proto.start(InputMethodServiceTraceFileProto.ENTRY); + proto.write(InputMethodServiceTraceProto.ELAPSED_REALTIME_NANOS, + SystemClock.elapsedRealtimeNanos()); + proto.write(InputMethodServiceTraceProto.WHERE, where); + proto.write(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE, protoDump); + proto.end(service_token); + break; + case IME_TRACING_FROM_IMMS: + final long managerservice_token = + proto.start(InputMethodManagerServiceTraceFileProto.ENTRY); + proto.write(InputMethodManagerServiceTraceProto.ELAPSED_REALTIME_NANOS, + SystemClock.elapsedRealtimeNanos()); + proto.write(InputMethodManagerServiceTraceProto.WHERE, where); + dumpDebug(proto, + InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE); + proto.end(managerservice_token); + break; + default: + // Dump triggered by a source not recognised. + return; + } + tracingInstance.addToBuffer(proto, source); } @BinderThread @Override - public void isImeTraceEnabled(IBooleanResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> ImeTracing.getInstance().isEnabled()); + public boolean isImeTraceEnabled() { + return ImeTracing.getInstance().isEnabled(); } @BinderThread @Override - public void startImeTrace(IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - ImeTracing.getInstance().startTrace(null /* printwriter */); - ArrayMap clients; - synchronized (mMethodMap) { - clients = new ArrayMap<>(mClients); - } - for (ClientState state : clients.values()) { - if (state != null) { - try { - state.client.setImeTraceEnabled(true /* enabled */); - } catch (RemoteException e) { - Slog.e(TAG, "Error while trying to enable ime trace on client window", e); - } + public void startImeTrace() { + ImeTracing.getInstance().startTrace(null /* printwriter */); + ArrayMap clients; + synchronized (mMethodMap) { + clients = new ArrayMap<>(mClients); + } + for (ClientState state : clients.values()) { + if (state != null) { + try { + state.client.setImeTraceEnabled(true /* enabled */); + } catch (RemoteException e) { + Slog.e(TAG, "Error while trying to enable ime trace on client window", e); } } - }); + } } @BinderThread @Override - public void stopImeTrace(IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - ImeTracing.getInstance().stopTrace(null /* printwriter */); - ArrayMap clients; - synchronized (mMethodMap) { - clients = new ArrayMap<>(mClients); - } - for (ClientState state : clients.values()) { - if (state != null) { - try { - state.client.setImeTraceEnabled(false /* enabled */); - } catch (RemoteException e) { - Slog.e(TAG, "Error while trying to disable ime trace on client window", e); - } + public void stopImeTrace() { + ImeTracing.getInstance().stopTrace(null /* printwriter */); + ArrayMap clients; + synchronized (mMethodMap) { + clients = new ArrayMap<>(mClients); + } + for (ClientState state : clients.values()) { + if (state != null) { + try { + state.client.setImeTraceEnabled(false /* enabled */); + } catch (RemoteException e) { + Slog.e(TAG, "Error while trying to disable ime trace on client window", e); } } - }); + } } private void dumpDebug(ProtoOutputStream proto, long fieldId) { @@ -4888,20 +4816,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub /** * Gets the current subtype of this input method. - * - * @param resultCallback to callback the result. */ @Override - 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(); + public InputMethodSubtype getCurrentInputMethodSubtype() { + synchronized (mMethodMap) { + // TODO: Make this work even for non-current users? + if (!calledFromValidUserLocked()) { + return null; } - }); + return getCurrentInputMethodSubtypeLocked(); + } } InputMethodSubtype getCurrentInputMethodSubtypeLocked() { diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index c97338ade7e86..ce195e6ddd645 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -72,17 +72,9 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; 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.IInputMethodInfoListResultCallback; -import com.android.internal.inputmethod.IInputMethodSubtypeListResultCallback; -import com.android.internal.inputmethod.IInputMethodSubtypeResultCallback; -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; @@ -112,7 +104,6 @@ import java.lang.annotation.Retention; import java.util.Collections; import java.util.List; import java.util.WeakHashMap; -import java.util.function.Supplier; /** * Actual implementation of multi-client InputMethodManagerService. @@ -1467,49 +1458,41 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void getInputMethodList(@UserIdInt int userId, - IInputMethodInfoListResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - if (UserHandle.getCallingUserId() != userId) { - mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null); - } - return mInputMethodInfoMap.getAsList(userId); - }); + public List getInputMethodList(@UserIdInt int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null); + } + return mInputMethodInfoMap.getAsList(userId); } @BinderThread @Override - public void getEnabledInputMethodList(@UserIdInt int userId, - IInputMethodInfoListResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { - if (UserHandle.getCallingUserId() != userId) { - mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null); - } - return mInputMethodInfoMap.getAsList(userId); - }); + public List getEnabledInputMethodList(@UserIdInt int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null); + } + return mInputMethodInfoMap.getAsList(userId); } @BinderThread @Override - public void getEnabledInputMethodSubtypeList(String imiId, - boolean allowsImplicitlySelectedSubtypes, - IInputMethodSubtypeListResultCallback resultCallback) { + public List getEnabledInputMethodSubtypeList(String imiId, + boolean allowsImplicitlySelectedSubtypes) { reportNotSupported(); - CallbackUtils.onResult(resultCallback, Collections::emptyList); + return Collections.emptyList(); } @BinderThread @Override - public void getLastInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) { + public InputMethodSubtype getLastInputMethodSubtype() { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> null); + return null; } @BinderThread @Override - public void removeImeSurface(IVoidResultCallback resultCallback) { + public void removeImeSurface() { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @@ -1520,11 +1503,10 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void showSoftInput( + public boolean showSoftInput( IInputMethodClient client, IBinder token, int flags, ResultReceiver resultReceiver, - @SoftInputShowHideReason int reason, IBooleanResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, - () -> showSoftInputInternal(client, token, flags, resultReceiver)); + @SoftInputShowHideReason int reason) { + return showSoftInputInternal(client, token, flags, resultReceiver); } @BinderThread @@ -1575,13 +1557,10 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void hideSoftInput( + public boolean hideSoftInput( IInputMethodClient client, IBinder windowToken, int flags, - ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, - IBooleanResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, - () -> hideSoftInputInternal(client, windowToken, flags, resultReceiver)); - + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + return hideSoftInputInternal(client, windowToken, flags, resultReceiver); } @BinderThread @@ -1628,34 +1607,7 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void reportWindowGainedFocusAsync( - boolean nextFocusHasConnection, - @Nullable IInputMethodClient client, - @Nullable IBinder windowToken, - @StartInputFlags int startInputFlags, - @SoftInputModeFlags int softInputMode, - int windowFlags, - int unverifiedTargetSdkVersion) { - final int startInputReason = nextFocusHasConnection - ? StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION - : StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION; - try { - startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken, - startInputFlags, softInputMode, windowFlags, null /* editorInfo */, - null /* inputContext */, 0 /* missingMethods */, - unverifiedTargetSdkVersion); - } catch (Throwable t) { - if (client != null) { - try { - client.throwExceptionFromSystem(t.getMessage()); - } catch (RemoteException ignore) { } - } - } - } - - @BinderThread - @Override - public void startInputOrWindowGainedFocus( + public InputBindResult startInputOrWindowGainedFocus( @StartInputReason int startInputReason, @Nullable IInputMethodClient client, @Nullable IBinder windowToken, @@ -1665,12 +1617,10 @@ public final class MultiClientInputMethodManagerService { @Nullable EditorInfo editorInfo, @Nullable IInputContext inputContext, @MissingMethodFlags int missingMethods, - int unverifiedTargetSdkVersion, - IInputBindResultResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, (Supplier) () -> - startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken, + int unverifiedTargetSdkVersion) { + return startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken, startInputFlags, softInputMode, windowFlags, editorInfo, inputContext, - missingMethods, unverifiedTargetSdkVersion)); + missingMethods, unverifiedTargetSdkVersion); } @BinderThread @@ -1812,54 +1762,49 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override public void showInputMethodPickerFromClient(IInputMethodClient client, - int auxiliarySubtypeMode, IVoidResultCallback resultCallback) { + int auxiliarySubtypeMode) { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @Override public void showInputMethodPickerFromSystem(IInputMethodClient client, - int auxiliarySubtypeMode, int displayId, IVoidResultCallback resultCallback) { + int auxiliarySubtypeMode, int displayId) { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @Override public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient client, - String inputMethodId, IVoidResultCallback resultCallback) { + String inputMethodId) { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @Override - public void isInputMethodPickerShownForTest(IBooleanResultCallback resultCallback) { + public boolean isInputMethodPickerShownForTest() { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> false); + return false; } @BinderThread @Override - public void getCurrentInputMethodSubtype(IInputMethodSubtypeResultCallback resultCallback) { + public InputMethodSubtype getCurrentInputMethodSubtype() { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> null); + return null; } @BinderThread @Override - public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes, - IVoidResultCallback resultCallback) { + public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> { }); } @BinderThread @Override - public void getInputMethodWindowVisibleHeight(IIntResultCallback resultCallback) { + public int getInputMethodWindowVisibleHeight() { reportNotSupported(); - CallbackUtils.onResult(resultCallback, () -> 0); + return 0; } @BinderThread @@ -1891,27 +1836,23 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public void startProtoDump(byte[] clientProtoDump, int source, String where, - IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { }); + public void startProtoDump(byte[] clientProtoDump, int source, String where) { } @BinderThread @Override - public void isImeTraceEnabled(IBooleanResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> false); + public boolean isImeTraceEnabled() { + return false; } @BinderThread @Override - public void startImeTrace(IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { }); + public void startImeTrace() { } @BinderThread @Override - public void stopImeTrace(IVoidResultCallback resultCallback) { - CallbackUtils.onResult(resultCallback, () -> { }); + public void stopImeTrace() { } } }