Loading services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +8 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,14 @@ final class InputMethodBindingController { mLatchForTesting = latchForTesting; } /** * Interface used to abstract {@code InputMethodBindingController} instantiation. */ interface Creator { InputMethodBindingController create(); } /** * Time that we last initiated a bind to the input method, to determine * if we should try to disconnect and reconnect to it. Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +60 −39 Original line number Diff line number Diff line Loading @@ -303,8 +303,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @MultiUserUnawareField private final InputMethodMenuController mMenuController; @MultiUserUnawareField @NonNull private final InputMethodBindingController mBindingController; @MultiUserUnawareField @NonNull private final AutofillSuggestionsController mAutofillController; @GuardedBy("ImfLock.class") Loading Loading @@ -465,12 +463,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable String getSelectedMethodIdLocked() { return mBindingController.getSelectedMethodId(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getSelectedMethodId(); } @GuardedBy("ImfLock.class") private void setSelectedMethodIdLocked(@Nullable String selectedMethodId) { mBindingController.setSelectedMethodId(selectedMethodId); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.setSelectedMethodId(selectedMethodId); } /** Loading @@ -479,8 +479,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private int getSequenceNumberLocked() { final UserData monitor = UserData.getOrCreate(mCurrentUserId); return monitor.mSequence.getSequenceNumber(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mSequence.getSequenceNumber(); } /** Loading Loading @@ -550,7 +550,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable private String getCurIdLocked() { return mBindingController.getCurId(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurId(); } /** Loading @@ -574,7 +575,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private boolean hasConnectionLocked() { return mBindingController.hasMainConnection(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.hasMainConnection(); } /** Loading @@ -597,7 +599,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable private Intent getCurIntentLocked() { return mBindingController.getCurIntent(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurIntent(); } /** Loading @@ -607,7 +610,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable IBinder getCurTokenLocked() { return mBindingController.getCurToken(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurToken(); } /** Loading Loading @@ -648,7 +652,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable IInputMethodInvoker getCurMethodLocked() { return mBindingController.getCurMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurMethod(); } /** Loading @@ -656,7 +661,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private int getCurMethodUidLocked() { return mBindingController.getCurMethodUid(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurMethodUid(); } /** Loading @@ -665,7 +671,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private long getLastBindTimeLocked() { return mBindingController.getLastBindTime(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getLastBindTime(); } /** Loading Loading @@ -1379,7 +1386,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // InputMethodSettingsRepository should be initialized before buildInputMethodListLocked InputMethodSettingsRepository.initialize(mHandler, mContext); AdditionalSubtypeMapRepository.initialize(mHandler, mContext); UserData.initialize(mHandler); mCurrentUserId = mActivityManagerInternal.getCurrentUserId(); Loading @@ -1392,19 +1398,17 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub new HardwareKeyboardShortcutController(settings.getMethodMap(), settings.getUserId()); mMenuController = new InputMethodMenuController(this); mBindingController = bindingControllerForTesting != null ? bindingControllerForTesting : new InputMethodBindingController(this); mAutofillController = new AutofillSuggestionsController(this); mVisibilityStateComputer = new ImeVisibilityStateComputer(this); mVisibilityApplier = new DefaultImeVisibilityApplier(this); mClientController = new ClientController(mPackageManagerInternal); synchronized (ImfLock.class) { mClientController.addClientControllerCallback(c -> onClientRemoved(c)); mImeBindingState = ImeBindingState.newEmptyState(); UserData.initialize(mHandler, /* bindingControllerCreator= */ () -> bindingControllerForTesting != null ? bindingControllerForTesting : new InputMethodBindingController(this)); } mPreventImeStartupUnlessTextEditor = mRes.getBoolean( Loading Loading @@ -1740,9 +1744,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Check if selected IME of current user supports handwriting. if (userId == mCurrentUserId) { return mBindingController.supportsStylusHandwriting() final UserData userData = UserData.getOrCreate(userId); final InputMethodBindingController bindingController = userData.mBindingController; return bindingController.supportsStylusHandwriting() && (!connectionless || mBindingController.supportsConnectionlessStylusHandwriting()); || bindingController.supportsConnectionlessStylusHandwriting()); } final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); final InputMethodInfo imi = settings.getMethodMap().get( Loading Loading @@ -2071,7 +2077,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker(); final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions = createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions); if (mBindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) { final UserData userData = UserData.getOrCreate(mCurrentUserId); if (userData.mBindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) { mHwController.setInkWindowInitializer(new InkWindowInitializer()); } return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION, Loading Loading @@ -2186,13 +2193,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mCurEditorInfo = editorInfo; // If configured, we want to avoid starting up the IME if it is not supposed to be showing final UserData userData = UserData.getOrCreate(mCurrentUserId); if (shouldPreventImeStartupLocked(selectedMethodId, startInputFlags, unverifiedTargetSdkVersion)) { if (DEBUG) { Slog.d(TAG, "Avoiding IME startup and unbinding current input method."); } invalidateAutofillSessionLocked(); mBindingController.unbindCurrentMethod(); userData.mBindingController.unbindCurrentMethod(); return InputBindResult.NO_EDITOR; } Loading Loading @@ -2224,9 +2232,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } mBindingController.unbindCurrentMethod(); return mBindingController.bindCurrentMethod(); userData.mBindingController.unbindCurrentMethod(); return userData.mBindingController.bindCurrentMethod(); } /** Loading Loading @@ -2489,7 +2496,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub setSelectedMethodIdLocked(null); // Callback before clean-up binding states. onUnbindCurrentMethodByReset(); mBindingController.unbindCurrentMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.unbindCurrentMethod(); unbindCurrentClientLocked(unbindClientReason); } Loading Loading @@ -3121,7 +3129,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Nullable String delegatorPackageName, @NonNull IConnectionlessHandwritingCallback callback) throws RemoteException { synchronized (ImfLock.class) { if (!mBindingController.supportsConnectionlessStylusHandwriting()) { final UserData userData = UserData.getOrCreate(mCurrentUserId); if (!userData.mBindingController.supportsConnectionlessStylusHandwriting()) { Slog.w(TAG, "Connectionless stylus handwriting mode unsupported by IME."); callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED); return; Loading Loading @@ -3187,9 +3196,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub + " startStylusHandwriting()"); return false; } final UserData userData = UserData.getOrCreate(mCurrentUserId); final long ident = Binder.clearCallingIdentity(); try { if (!mBindingController.supportsStylusHandwriting()) { if (!userData.mBindingController.supportsStylusHandwriting()) { Slog.w(TAG, "Stylus HW unsupported by IME. Ignoring startStylusHandwriting()"); return false; Loading Loading @@ -3368,7 +3378,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mVisibilityStateComputer.requestImeVisibility(windowToken, true); // Ensure binding the connection when IME is going to show. mBindingController.setCurrentMethodVisible(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.setCurrentMethodVisible(); final IInputMethodInvoker curMethod = getCurMethodLocked(); ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME); if (curMethod != null) { Loading Loading @@ -3471,7 +3482,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } else { ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); } mBindingController.setCurrentMethodNotVisible(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.setCurrentMethodNotVisible(); mVisibilityStateComputer.clearImeShowFlags(); // Cancel existing statsToken for show IME as we got a hide request. ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME); Loading Loading @@ -3753,7 +3765,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Note that we can trust client's display ID as long as it matches // to the display ID obtained from the window. if (cs.mSelfReportedDisplayId != mCurTokenDisplayId) { mBindingController.unbindCurrentMethod(); final UserData userData = UserData.getOrCreate(userId); userData.mBindingController.unbindCurrentMethod(); } } } Loading Loading @@ -4209,6 +4222,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub }, mHandler); } @GuardedBy("ImfLock.class") private void addStylusDeviceIdLocked(int deviceId) { if (mStylusIds == null) { mStylusIds = new IntArray(); Loading @@ -4219,8 +4233,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mStylusIds.add(deviceId); // a new Stylus is detected. If IME supports handwriting, and we don't have // handwriting initialized, lets do it now. final UserData userData = UserData.getOrCreate(mCurrentUserId); final InputMethodBindingController bindingController = userData.mBindingController; if (!mHwController.getCurrentRequestId().isPresent() && mBindingController.supportsStylusHandwriting()) { && bindingController.supportsStylusHandwriting()) { scheduleResetStylusHandwriting(); } } Loading Loading @@ -4796,7 +4812,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub case MSG_RESET_HANDWRITING: { synchronized (ImfLock.class) { if (mBindingController.supportsStylusHandwriting() final UserData userData = UserData.getOrCreate(mCurrentUserId); if (userData.mBindingController.supportsStylusHandwriting() && getCurMethodLocked() != null && hasSupportedStylusLocked()) { Slog.d(TAG, "Initializing Handwriting Spy"); mHwController.initializeHandwritingSpy(mCurTokenDisplayId); Loading @@ -4821,11 +4838,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (curMethod == null || mImeBindingState.mFocusedWindow == null) { return true; } final UserData userData = UserData.getOrCreate(mCurrentUserId); final HandwritingModeController.HandwritingSession session = mHwController.startHandwritingSession( msg.arg1 /*requestId*/, msg.arg2 /*pid*/, mBindingController.getCurMethodUid(), userData.mBindingController.getCurMethodUid(), mImeBindingState.mFocusedWindow); if (session == null) { Slog.e(TAG, Loading Loading @@ -5119,7 +5137,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") void sendOnNavButtonFlagsChangedLocked() { final IInputMethodInvoker curMethod = mBindingController.getCurMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); final IInputMethodInvoker curMethod = userData.mBindingController.getCurMethod(); if (curMethod == null) { // No need to send the data if the IME is not yet bound. return; Loading Loading @@ -5876,9 +5895,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub p.println(" mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked()); p.println(" mFocusedWindowPerceptible=" + mFocusedWindowPerceptible); mImeBindingState.dump(" ", p); final UserData userData = UserData.getOrCreate(mCurrentUserId); p.println(" mCurId=" + getCurIdLocked() + " mHaveConnection=" + hasConnectionLocked() + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound=" + mBindingController.isVisibleBound()); + userData.mBindingController.isVisibleBound()); p.println(" mCurToken=" + getCurTokenLocked()); p.println(" mCurTokenDisplayId=" + mCurTokenDisplayId); p.println(" mCurHostInputToken=" + mCurHostInputToken); Loading Loading @@ -6372,7 +6392,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (userId == mCurrentUserId) { hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */, SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND); mBindingController.unbindCurrentMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.unbindCurrentMethod(); // Enable default IMEs, disable others var toDisable = settings.getEnabledInputMethodList(); Loading services/core/java/com/android/server/inputmethod/UserData.java +21 −10 Original line number Diff line number Diff line Loading @@ -28,8 +28,10 @@ import com.android.server.pm.UserManagerInternal; final class UserData { @NonNull private static final SparseArray<UserData> sPerUserMonitor = new SparseArray<>(); private static SparseArray<UserData> sUserData; @GuardedBy("ImfLock.class") private static InputMethodBindingController.Creator sBindingControllerCreator; @UserIdInt final int mUserId; Loading @@ -37,24 +39,33 @@ final class UserData { @GuardedBy("ImfLock.class") final Sequence mSequence = new Sequence(); @NonNull final InputMethodBindingController mBindingController; /** * Not intended to be instantiated. */ private UserData(int userId) { private UserData(int userId, InputMethodBindingController bindingController) { mUserId = userId; mBindingController = bindingController; } @GuardedBy("ImfLock.class") static UserData getOrCreate(@UserIdInt int userId) { UserData monitor = sPerUserMonitor.get(userId); if (monitor == null) { monitor = new UserData(userId); sPerUserMonitor.put(userId, monitor); UserData userData = sUserData.get(userId); if (userData == null) { userData = new UserData(userId, sBindingControllerCreator.create()); sUserData.put(userId, userData); } return monitor; return userData; } static void initialize(Handler handler) { @GuardedBy("ImfLock.class") static void initialize(Handler handler, InputMethodBindingController.Creator bindingControllerCreator) { sUserData = new SparseArray<>(); sBindingControllerCreator = bindingControllerCreator; final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); userManagerInternal.addUserLifecycleListener( Loading @@ -64,7 +75,7 @@ final class UserData { final int userId = user.id; handler.post(() -> { synchronized (ImfLock.class) { sPerUserMonitor.remove(userId); sUserData.remove(userId); } }); } Loading Loading
services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +8 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,14 @@ final class InputMethodBindingController { mLatchForTesting = latchForTesting; } /** * Interface used to abstract {@code InputMethodBindingController} instantiation. */ interface Creator { InputMethodBindingController create(); } /** * Time that we last initiated a bind to the input method, to determine * if we should try to disconnect and reconnect to it. Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +60 −39 Original line number Diff line number Diff line Loading @@ -303,8 +303,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @MultiUserUnawareField private final InputMethodMenuController mMenuController; @MultiUserUnawareField @NonNull private final InputMethodBindingController mBindingController; @MultiUserUnawareField @NonNull private final AutofillSuggestionsController mAutofillController; @GuardedBy("ImfLock.class") Loading Loading @@ -465,12 +463,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable String getSelectedMethodIdLocked() { return mBindingController.getSelectedMethodId(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getSelectedMethodId(); } @GuardedBy("ImfLock.class") private void setSelectedMethodIdLocked(@Nullable String selectedMethodId) { mBindingController.setSelectedMethodId(selectedMethodId); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.setSelectedMethodId(selectedMethodId); } /** Loading @@ -479,8 +479,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private int getSequenceNumberLocked() { final UserData monitor = UserData.getOrCreate(mCurrentUserId); return monitor.mSequence.getSequenceNumber(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mSequence.getSequenceNumber(); } /** Loading Loading @@ -550,7 +550,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable private String getCurIdLocked() { return mBindingController.getCurId(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurId(); } /** Loading @@ -574,7 +575,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private boolean hasConnectionLocked() { return mBindingController.hasMainConnection(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.hasMainConnection(); } /** Loading @@ -597,7 +599,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable private Intent getCurIntentLocked() { return mBindingController.getCurIntent(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurIntent(); } /** Loading @@ -607,7 +610,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable IBinder getCurTokenLocked() { return mBindingController.getCurToken(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurToken(); } /** Loading Loading @@ -648,7 +652,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") @Nullable IInputMethodInvoker getCurMethodLocked() { return mBindingController.getCurMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurMethod(); } /** Loading @@ -656,7 +661,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private int getCurMethodUidLocked() { return mBindingController.getCurMethodUid(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getCurMethodUid(); } /** Loading @@ -665,7 +671,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub */ @GuardedBy("ImfLock.class") private long getLastBindTimeLocked() { return mBindingController.getLastBindTime(); final UserData userData = UserData.getOrCreate(mCurrentUserId); return userData.mBindingController.getLastBindTime(); } /** Loading Loading @@ -1379,7 +1386,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // InputMethodSettingsRepository should be initialized before buildInputMethodListLocked InputMethodSettingsRepository.initialize(mHandler, mContext); AdditionalSubtypeMapRepository.initialize(mHandler, mContext); UserData.initialize(mHandler); mCurrentUserId = mActivityManagerInternal.getCurrentUserId(); Loading @@ -1392,19 +1398,17 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub new HardwareKeyboardShortcutController(settings.getMethodMap(), settings.getUserId()); mMenuController = new InputMethodMenuController(this); mBindingController = bindingControllerForTesting != null ? bindingControllerForTesting : new InputMethodBindingController(this); mAutofillController = new AutofillSuggestionsController(this); mVisibilityStateComputer = new ImeVisibilityStateComputer(this); mVisibilityApplier = new DefaultImeVisibilityApplier(this); mClientController = new ClientController(mPackageManagerInternal); synchronized (ImfLock.class) { mClientController.addClientControllerCallback(c -> onClientRemoved(c)); mImeBindingState = ImeBindingState.newEmptyState(); UserData.initialize(mHandler, /* bindingControllerCreator= */ () -> bindingControllerForTesting != null ? bindingControllerForTesting : new InputMethodBindingController(this)); } mPreventImeStartupUnlessTextEditor = mRes.getBoolean( Loading Loading @@ -1740,9 +1744,11 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Check if selected IME of current user supports handwriting. if (userId == mCurrentUserId) { return mBindingController.supportsStylusHandwriting() final UserData userData = UserData.getOrCreate(userId); final InputMethodBindingController bindingController = userData.mBindingController; return bindingController.supportsStylusHandwriting() && (!connectionless || mBindingController.supportsConnectionlessStylusHandwriting()); || bindingController.supportsConnectionlessStylusHandwriting()); } final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); final InputMethodInfo imi = settings.getMethodMap().get( Loading Loading @@ -2071,7 +2077,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker(); final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions = createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions); if (mBindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) { final UserData userData = UserData.getOrCreate(mCurrentUserId); if (userData.mBindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) { mHwController.setInkWindowInitializer(new InkWindowInitializer()); } return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION, Loading Loading @@ -2186,13 +2193,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mCurEditorInfo = editorInfo; // If configured, we want to avoid starting up the IME if it is not supposed to be showing final UserData userData = UserData.getOrCreate(mCurrentUserId); if (shouldPreventImeStartupLocked(selectedMethodId, startInputFlags, unverifiedTargetSdkVersion)) { if (DEBUG) { Slog.d(TAG, "Avoiding IME startup and unbinding current input method."); } invalidateAutofillSessionLocked(); mBindingController.unbindCurrentMethod(); userData.mBindingController.unbindCurrentMethod(); return InputBindResult.NO_EDITOR; } Loading Loading @@ -2224,9 +2232,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } mBindingController.unbindCurrentMethod(); return mBindingController.bindCurrentMethod(); userData.mBindingController.unbindCurrentMethod(); return userData.mBindingController.bindCurrentMethod(); } /** Loading Loading @@ -2489,7 +2496,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub setSelectedMethodIdLocked(null); // Callback before clean-up binding states. onUnbindCurrentMethodByReset(); mBindingController.unbindCurrentMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.unbindCurrentMethod(); unbindCurrentClientLocked(unbindClientReason); } Loading Loading @@ -3121,7 +3129,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Nullable String delegatorPackageName, @NonNull IConnectionlessHandwritingCallback callback) throws RemoteException { synchronized (ImfLock.class) { if (!mBindingController.supportsConnectionlessStylusHandwriting()) { final UserData userData = UserData.getOrCreate(mCurrentUserId); if (!userData.mBindingController.supportsConnectionlessStylusHandwriting()) { Slog.w(TAG, "Connectionless stylus handwriting mode unsupported by IME."); callback.onError(CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED); return; Loading Loading @@ -3187,9 +3196,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub + " startStylusHandwriting()"); return false; } final UserData userData = UserData.getOrCreate(mCurrentUserId); final long ident = Binder.clearCallingIdentity(); try { if (!mBindingController.supportsStylusHandwriting()) { if (!userData.mBindingController.supportsStylusHandwriting()) { Slog.w(TAG, "Stylus HW unsupported by IME. Ignoring startStylusHandwriting()"); return false; Loading Loading @@ -3368,7 +3378,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mVisibilityStateComputer.requestImeVisibility(windowToken, true); // Ensure binding the connection when IME is going to show. mBindingController.setCurrentMethodVisible(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.setCurrentMethodVisible(); final IInputMethodInvoker curMethod = getCurMethodLocked(); ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME); if (curMethod != null) { Loading Loading @@ -3471,7 +3482,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } else { ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); } mBindingController.setCurrentMethodNotVisible(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.setCurrentMethodNotVisible(); mVisibilityStateComputer.clearImeShowFlags(); // Cancel existing statsToken for show IME as we got a hide request. ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME); Loading Loading @@ -3753,7 +3765,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Note that we can trust client's display ID as long as it matches // to the display ID obtained from the window. if (cs.mSelfReportedDisplayId != mCurTokenDisplayId) { mBindingController.unbindCurrentMethod(); final UserData userData = UserData.getOrCreate(userId); userData.mBindingController.unbindCurrentMethod(); } } } Loading Loading @@ -4209,6 +4222,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub }, mHandler); } @GuardedBy("ImfLock.class") private void addStylusDeviceIdLocked(int deviceId) { if (mStylusIds == null) { mStylusIds = new IntArray(); Loading @@ -4219,8 +4233,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mStylusIds.add(deviceId); // a new Stylus is detected. If IME supports handwriting, and we don't have // handwriting initialized, lets do it now. final UserData userData = UserData.getOrCreate(mCurrentUserId); final InputMethodBindingController bindingController = userData.mBindingController; if (!mHwController.getCurrentRequestId().isPresent() && mBindingController.supportsStylusHandwriting()) { && bindingController.supportsStylusHandwriting()) { scheduleResetStylusHandwriting(); } } Loading Loading @@ -4796,7 +4812,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub case MSG_RESET_HANDWRITING: { synchronized (ImfLock.class) { if (mBindingController.supportsStylusHandwriting() final UserData userData = UserData.getOrCreate(mCurrentUserId); if (userData.mBindingController.supportsStylusHandwriting() && getCurMethodLocked() != null && hasSupportedStylusLocked()) { Slog.d(TAG, "Initializing Handwriting Spy"); mHwController.initializeHandwritingSpy(mCurTokenDisplayId); Loading @@ -4821,11 +4838,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (curMethod == null || mImeBindingState.mFocusedWindow == null) { return true; } final UserData userData = UserData.getOrCreate(mCurrentUserId); final HandwritingModeController.HandwritingSession session = mHwController.startHandwritingSession( msg.arg1 /*requestId*/, msg.arg2 /*pid*/, mBindingController.getCurMethodUid(), userData.mBindingController.getCurMethodUid(), mImeBindingState.mFocusedWindow); if (session == null) { Slog.e(TAG, Loading Loading @@ -5119,7 +5137,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @GuardedBy("ImfLock.class") void sendOnNavButtonFlagsChangedLocked() { final IInputMethodInvoker curMethod = mBindingController.getCurMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); final IInputMethodInvoker curMethod = userData.mBindingController.getCurMethod(); if (curMethod == null) { // No need to send the data if the IME is not yet bound. return; Loading Loading @@ -5876,9 +5895,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub p.println(" mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked()); p.println(" mFocusedWindowPerceptible=" + mFocusedWindowPerceptible); mImeBindingState.dump(" ", p); final UserData userData = UserData.getOrCreate(mCurrentUserId); p.println(" mCurId=" + getCurIdLocked() + " mHaveConnection=" + hasConnectionLocked() + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound=" + mBindingController.isVisibleBound()); + userData.mBindingController.isVisibleBound()); p.println(" mCurToken=" + getCurTokenLocked()); p.println(" mCurTokenDisplayId=" + mCurTokenDisplayId); p.println(" mCurHostInputToken=" + mCurHostInputToken); Loading Loading @@ -6372,7 +6392,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (userId == mCurrentUserId) { hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */, SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND); mBindingController.unbindCurrentMethod(); final UserData userData = UserData.getOrCreate(mCurrentUserId); userData.mBindingController.unbindCurrentMethod(); // Enable default IMEs, disable others var toDisable = settings.getEnabledInputMethodList(); Loading
services/core/java/com/android/server/inputmethod/UserData.java +21 −10 Original line number Diff line number Diff line Loading @@ -28,8 +28,10 @@ import com.android.server.pm.UserManagerInternal; final class UserData { @NonNull private static final SparseArray<UserData> sPerUserMonitor = new SparseArray<>(); private static SparseArray<UserData> sUserData; @GuardedBy("ImfLock.class") private static InputMethodBindingController.Creator sBindingControllerCreator; @UserIdInt final int mUserId; Loading @@ -37,24 +39,33 @@ final class UserData { @GuardedBy("ImfLock.class") final Sequence mSequence = new Sequence(); @NonNull final InputMethodBindingController mBindingController; /** * Not intended to be instantiated. */ private UserData(int userId) { private UserData(int userId, InputMethodBindingController bindingController) { mUserId = userId; mBindingController = bindingController; } @GuardedBy("ImfLock.class") static UserData getOrCreate(@UserIdInt int userId) { UserData monitor = sPerUserMonitor.get(userId); if (monitor == null) { monitor = new UserData(userId); sPerUserMonitor.put(userId, monitor); UserData userData = sUserData.get(userId); if (userData == null) { userData = new UserData(userId, sBindingControllerCreator.create()); sUserData.put(userId, userData); } return monitor; return userData; } static void initialize(Handler handler) { @GuardedBy("ImfLock.class") static void initialize(Handler handler, InputMethodBindingController.Creator bindingControllerCreator) { sUserData = new SparseArray<>(); sBindingControllerCreator = bindingControllerCreator; final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); userManagerInternal.addUserLifecycleListener( Loading @@ -64,7 +75,7 @@ final class UserData { final int userId = user.id; handler.post(() -> { synchronized (ImfLock.class) { sPerUserMonitor.remove(userId); sUserData.remove(userId); } }); } Loading