summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java73
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java5
2 files changed, 42 insertions, 36 deletions
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index b0d734df37b4..9ac7f1b731fc 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -88,6 +88,7 @@ import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocaleList;
+import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -922,18 +923,45 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
public static final class Lifecycle extends SystemService {
private final InputMethodManagerService mService;
-
public Lifecycle(Context context) {
- this(context, new InputMethodManagerService(context,
- shouldEnableConcurrentMultiUserMode(context)));
+ this(context, createServiceForProduction(context));
}
- public Lifecycle(
- Context context, @NonNull InputMethodManagerService inputMethodManagerService) {
+ @VisibleForTesting
+ Lifecycle(Context context, @NonNull InputMethodManagerService inputMethodManagerService) {
super(context);
mService = inputMethodManagerService;
}
+ /**
+ * Does initialization then instantiate {@link InputMethodManagerService} for production
+ * configurations.
+ *
+ * <p>We have this abstraction just because several unit tests directly initialize
+ * {@link InputMethodManagerService} with some mocked/emulated dependencies.</p>
+ *
+ * @param context {@link Context} to be used to set up
+ * @return {@link InputMethodManagerService} object to be used
+ */
+ @NonNull
+ private static InputMethodManagerService createServiceForProduction(
+ @NonNull Context context) {
+ // TODO(b/196206770): Disallow I/O on this thread. Currently it's needed for loading
+ // additional subtypes in switchUserOnHandlerLocked().
+ final ServiceThread thread = new ServiceThread(HANDLER_THREAD_NAME,
+ Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+ thread.start();
+
+ final ServiceThread ioThread = new ServiceThread(PACKAGE_MONITOR_THREAD_NAME,
+ Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+ ioThread.start();
+
+ return new InputMethodManagerService(context,
+ shouldEnableConcurrentMultiUserMode(context), thread.getLooper(),
+ Handler.createAsync(ioThread.getLooper()),
+ null /* bindingControllerForTesting */);
+ }
+
@Override
public void onStart() {
mService.publishLocalService();
@@ -1041,17 +1069,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mHandler.post(task);
}
- public InputMethodManagerService(Context context,
- boolean concurrentMultiUserModeEnabled) {
- this(context, concurrentMultiUserModeEnabled, null, null, null);
- }
-
@VisibleForTesting
InputMethodManagerService(
Context context,
boolean concurrentMultiUserModeEnabled,
- @Nullable ServiceThread serviceThreadForTesting,
- @Nullable ServiceThread ioThreadForTesting,
+ @NonNull Looper uiLooper,
+ @NonNull Handler ioHandler,
@Nullable IntFunction<InputMethodBindingController> bindingControllerForTesting) {
synchronized (ImfLock.class) {
mConcurrentMultiUserModeEnabled = concurrentMultiUserModeEnabled;
@@ -1059,28 +1082,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mRes = context.getResources();
SecureSettingsWrapper.onStart(mContext);
- // TODO(b/196206770): Disallow I/O on this thread. Currently it's needed for loading
- // additional subtypes in switchUserOnHandlerLocked().
- final ServiceThread thread =
- serviceThreadForTesting != null
- ? serviceThreadForTesting
- : new ServiceThread(
- HANDLER_THREAD_NAME,
- Process.THREAD_PRIORITY_FOREGROUND,
- true /* allowIo */);
- thread.start();
- mHandler = Handler.createAsync(thread.getLooper(), this);
- {
- final ServiceThread ioThread =
- ioThreadForTesting != null
- ? ioThreadForTesting
- : new ServiceThread(
- PACKAGE_MONITOR_THREAD_NAME,
- Process.THREAD_PRIORITY_FOREGROUND,
- true /* allowIo */);
- ioThread.start();
- mIoHandler = Handler.createAsync(ioThread.getLooper());
- }
+ mHandler = Handler.createAsync(uiLooper, this);
+ mIoHandler = ioHandler;
SystemLocaleWrapper.onStart(context, this::onActionLocaleChanged, mHandler);
mImeTrackerService = new ImeTrackerService(mHandler);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
@@ -1128,7 +1131,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
mNonPreemptibleInputMethods = mRes.getStringArray(
com.android.internal.R.array.config_nonPreemptibleInputMethods);
Runnable discardDelegationTextRunnable = () -> discardHandwritingDelegationText();
- mHwController = new HandwritingModeController(mContext, thread.getLooper(),
+ mHwController = new HandwritingModeController(mContext, uiLooper,
new InkWindowInitializer(), discardDelegationTextRunnable);
registerDeviceListenerAndCheckStylusSupport();
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
index 17d9ef9fad34..ff308d9952f9 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -41,6 +41,7 @@ import android.content.res.Configuration;
import android.hardware.input.IInputManager;
import android.hardware.input.InputManagerGlobal;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
@@ -227,14 +228,16 @@ public class InputMethodManagerServiceTestBase {
"immstest1",
Process.THREAD_PRIORITY_FOREGROUND,
true /* allowIo */);
+ mServiceThread.start();
mIoThread =
new ServiceThread(
"immstest2",
Process.THREAD_PRIORITY_FOREGROUND,
true /* allowIo */);
+ mIoThread.start();
mInputMethodManagerService = new InputMethodManagerService(mContext,
InputMethodManagerService.shouldEnableConcurrentMultiUserMode(mContext),
- mServiceThread, mIoThread,
+ mServiceThread.getLooper(), Handler.createAsync(mIoThread.getLooper()),
unusedUserId -> mMockInputMethodBindingController);
spyOn(mInputMethodManagerService);