diff options
| author | 2024-06-21 22:39:13 +0000 | |
|---|---|---|
| committer | 2024-06-21 22:39:13 +0000 | |
| commit | 6d408a9ef675c11a1c804e6d49622b29e1985ec0 (patch) | |
| tree | 8c2b85dc0200e670858d162d52858a33d96998cf | |
| parent | 8d4db72240e949c95a00fb469e5814957ed5f680 (diff) | |
| parent | deca4f9ff597290d9c13016dc5599cb96e2e0bd1 (diff) | |
Merge "Make ImeVisibiltyApplier show/hide IME per user" into main
4 files changed, 69 insertions, 51 deletions
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java index 7d485271e35c..b77f47d640e9 100644 --- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java +++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java @@ -69,7 +69,6 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { @NonNull private final ImeTargetVisibilityPolicy mImeTargetVisibilityPolicy; - DefaultImeVisibilityApplier(InputMethodManagerService service) { mService = service; mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); @@ -80,8 +79,9 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { @Override public void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken, @InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver, - @SoftInputShowHideReason int reason) { - final IInputMethodInvoker curMethod = mService.getCurMethodLocked(); + @SoftInputShowHideReason int reason, @UserIdInt int userId) { + final var bindingController = mService.getInputMethodBindingController(userId); + final IInputMethodInvoker curMethod = bindingController.getCurMethod(); if (curMethod != null) { if (DEBUG) { Slog.v(TAG, "Calling " + curMethod + ".showSoftInput(" + showInputToken @@ -99,7 +99,7 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { mService.mImeBindingState.mFocusedWindowSoftInputMode)); } mService.onShowHideSoftInputRequested(true /* show */, showInputToken, reason, - statsToken); + statsToken, userId); } } } @@ -107,8 +107,10 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { @GuardedBy("ImfLock.class") @Override public void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken, - ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { - final IInputMethodInvoker curMethod = mService.getCurMethodLocked(); + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, + @UserIdInt int userId) { + final var bindingController = mService.getInputMethodBindingController(userId); + final IInputMethodInvoker curMethod = bindingController.getCurMethod(); if (curMethod != null) { // The IME will report its visible state again after the following message finally // delivered to the IME process as an IPC. Hence the inconsistency between @@ -130,7 +132,7 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { mService.mImeBindingState.mFocusedWindowSoftInputMode)); } mService.onShowHideSoftInputRequested(false /* show */, hideInputToken, reason, - statsToken); + statsToken, userId); } } } @@ -180,7 +182,7 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { setImeVisibilityOnFocusedWindowClient(false); } else { mService.hideCurrentInputLocked(windowToken, statsToken, - 0 /* flags */, null /* resultReceiver */, reason); + 0 /* flags */, null /* resultReceiver */, reason); } break; case STATE_HIDE_IME_NOT_ALWAYS: @@ -199,14 +201,14 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { } else { mService.showCurrentInputLocked(windowToken, statsToken, InputMethodManager.SHOW_IMPLICIT, MotionEvent.TOOL_TYPE_UNKNOWN, - null /* resultReceiver */, reason); + null /* resultReceiver */, reason); } break; case STATE_SHOW_IME_SNAPSHOT: - showImeScreenshot(windowToken, displayIdToShowIme); + showImeScreenshot(windowToken, displayIdToShowIme, userId); break; case STATE_REMOVE_IME_SNAPSHOT: - removeImeScreenshot(displayIdToShowIme); + removeImeScreenshot(displayIdToShowIme, userId); break; default: throw new IllegalArgumentException("Invalid IME visibility state: " + state); @@ -215,10 +217,11 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { @GuardedBy("ImfLock.class") @Override - public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId) { + public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId, + @UserIdInt int userId) { if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) { mService.onShowHideSoftInputRequested(false /* show */, imeTarget, - SHOW_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */); + SHOW_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId); return true; } return false; @@ -226,11 +229,11 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { @GuardedBy("ImfLock.class") @Override - public boolean removeImeScreenshot(int displayId) { + public boolean removeImeScreenshot(int displayId, @UserIdInt int userId) { if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) { mService.onShowHideSoftInputRequested(false /* show */, mService.mImeBindingState.mFocusedWindow, - REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */); + REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId); return true; } return false; diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java index a5f9b7a986c9..c1069f2a23d7 100644 --- a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java +++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java @@ -33,38 +33,45 @@ interface ImeVisibilityApplier { /** * Performs showing IME on top of the given window. * - * @param showInputToken A token that represents the requester to show IME. - * @param statsToken The token tracking the current IME request. - * @param resultReceiver If non-null, this will be called back to the caller when - * it has processed request to tell what it has done. - * @param reason The reason for requesting to show IME. + * @param showInputToken a token that represents the requester to show IME + * @param statsToken the token tracking the current IME request + * @param resultReceiver if non-null, this will be called back to the caller when + * it has processed request to tell what it has done + * @param reason yhe reason for requesting to show IME + * @param userId the target user when performing show IME */ default void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken, @InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver, - @SoftInputShowHideReason int reason) {} + @SoftInputShowHideReason int reason, @UserIdInt int userId) { + } /** * Performs hiding IME to the given window * - * @param hideInputToken A token that represents the requester to hide IME. - * @param statsToken The token tracking the current IME request. - * @param resultReceiver If non-null, this will be called back to the caller when - * it has processed request to tell what it has done. - * @param reason The reason for requesting to hide IME. + * @param hideInputToken a token that represents the requester to hide IME + * @param statsToken the token tracking the current IME request + * @param resultReceiver if non-null, this will be called back to the caller when + * it has processed request to tell what it has done + * @param reason the reason for requesting to hide IME + * @param userId the target user when performing hide IME */ default void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken, - ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {} + ResultReceiver resultReceiver, @SoftInputShowHideReason int reason, + @UserIdInt int userId) { + } /** * Applies the IME visibility from {@link android.inputmethodservice.InputMethodService} with * according to the given visibility state. * - * @param windowToken The token of a window for applying the IME visibility - * @param statsToken The token tracking the current IME request. - * @param state The new IME visibility state for the applier to handle + * @param windowToken the token of a window for applying the IME visibility + * @param statsToken the token tracking the current IME request + * @param state the new IME visibility state for the applier to handle + * @param userId the target user when applying the IME visibility state */ default void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken, - @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {} + @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) { + } /** * Updates the IME Z-ordering relative to the given window. @@ -72,7 +79,7 @@ interface ImeVisibilityApplier { * This used to adjust the IME relative layer of the window during * {@link InputMethodManagerService} is in switching IME clients. * - * @param windowToken The token of a window to update the Z-ordering relative to the IME. + * @param windowToken the token of a window to update the Z-ordering relative to the IME */ default void updateImeLayeringByTarget(IBinder windowToken) { // TODO: add a method in WindowManagerInternal to call DC#updateImeInputAndControlTarget @@ -82,21 +89,24 @@ interface ImeVisibilityApplier { /** * Shows the IME screenshot and attach it to the given IME target window. * - * @param windowToken The token of a window to show the IME screenshot. - * @param displayId The unique id to identify the display - * @return {@code true} if success, {@code false} otherwise. + * @param windowToken the token of a window to show the IME screenshot + * @param displayId the unique id to identify the display + * @param userId the target user when when showing the IME screenshot + * @return {@code true} if success, {@code false} otherwise */ - default boolean showImeScreenshot(@NonNull IBinder windowToken, int displayId) { + default boolean showImeScreenshot(@NonNull IBinder windowToken, int displayId, + @UserIdInt int userId) { return false; } /** * Removes the IME screenshot on the given display. * - * @param displayId The target display of showing IME screenshot. - * @return {@code true} if success, {@code false} otherwise. + * @param displayId the target display of showing IME screenshot + * @param userId the target user of showing IME screenshot + * @return {@code true} if success, {@code false} otherwise */ - default boolean removeImeScreenshot(int displayId) { + default boolean removeImeScreenshot(int displayId, @UserIdInt int userId) { return false; } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index af2bc34a1ea1..00c408f7199a 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3509,10 +3509,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. mVisibilityStateComputer.requestImeVisibility(windowToken, true); + final int userId = mCurrentUserId; // Ensure binding the connection when IME is going to show. - final var bindingController = getInputMethodBindingController(mCurrentUserId); + final var bindingController = getInputMethodBindingController(userId); bindingController.setCurrentMethodVisible(); - final IInputMethodInvoker curMethod = getCurMethodLocked(); + final IInputMethodInvoker curMethod = bindingController.getCurMethod(); ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME); final boolean readyToDispatchToIme; if (Flags.deferShowSoftInputUntilSessionCreation()) { @@ -3532,7 +3533,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } mVisibilityApplier.performShowIme(windowToken, statsToken, mVisibilityStateComputer.getShowFlagsForInputMethodServiceOnly(), - resultReceiver, reason); + resultReceiver, reason, userId); mVisibilityStateComputer.setInputShown(true); return true; } else { @@ -3644,7 +3645,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. // since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only // IMMS#InputShown indicates that the software keyboard is shown. // TODO(b/246309664): Clean up IMMS#mImeWindowVis - IInputMethodInvoker curMethod = getCurMethodLocked(); + final int userId = mCurrentUserId; + final var bindingController = getInputMethodBindingController(userId); + IInputMethodInvoker curMethod = bindingController.getCurMethod(); final boolean shouldHideSoftInput = curMethod != null && (isInputShownLocked() || (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0); @@ -3655,11 +3658,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in // the final state. ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); - mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason); + mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason, + userId); } else { ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE); } - final var bindingController = getInputMethodBindingController(mCurrentUserId); bindingController.setCurrentMethodNotVisible(); mVisibilityStateComputer.clearImeShowFlags(); // Cancel existing statsToken for show IME as we got a hide request. @@ -4725,12 +4728,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. */ @GuardedBy("ImfLock.class") void onShowHideSoftInputRequested(boolean show, IBinder requestImeToken, - @SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken) { + @SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken, + @UserIdInt int userId) { final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken); + final var bindingController = getInputMethodBindingController(userId); final WindowManagerInternal.ImeTargetInfo info = mWindowManagerInternal.onToggleImeRequested( show, mImeBindingState.mFocusedWindow, requestToken, - getCurTokenDisplayIdLocked()); + bindingController.getCurTokenDisplayId()); mSoftInputShowHideHistory.addEntry(new SoftInputShowHideHistory.Entry( mImeBindingState.mFocusedWindowClient, mImeBindingState.mFocusedWindowEditorInfo, info.focusedWindowName, mImeBindingState.mFocusedWindowSoftInputMode, reason, diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java index a4ca317ce914..d4adba209cd9 100644 --- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java +++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java @@ -87,7 +87,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe synchronized (ImfLock.class) { mVisibilityApplier.performShowIme(new Binder() /* showInputToken */, ImeTracker.Token.empty(), 0 /* showFlags */, null /* resultReceiver */, - SHOW_SOFT_INPUT); + SHOW_SOFT_INPUT, mUserId); } verifyShowSoftInput(false, true, 0 /* showFlags */); } @@ -96,7 +96,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe public void testPerformHideIme() throws Exception { synchronized (ImfLock.class) { mVisibilityApplier.performHideIme(new Binder() /* hideInputToken */, - ImeTracker.Token.empty(), null /* resultReceiver */, HIDE_SOFT_INPUT); + ImeTracker.Token.empty(), null /* resultReceiver */, HIDE_SOFT_INPUT, mUserId); } verifyHideSoftInput(false, true); } @@ -186,7 +186,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe @Test public void testShowImeScreenshot() { synchronized (ImfLock.class) { - mVisibilityApplier.showImeScreenshot(mWindowToken, Display.DEFAULT_DISPLAY); + mVisibilityApplier.showImeScreenshot(mWindowToken, Display.DEFAULT_DISPLAY, mUserId); } verify(mMockImeTargetVisibilityPolicy).showImeScreenshot(eq(mWindowToken), @@ -196,7 +196,7 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe @Test public void testRemoveImeScreenshot() { synchronized (ImfLock.class) { - mVisibilityApplier.removeImeScreenshot(Display.DEFAULT_DISPLAY); + mVisibilityApplier.removeImeScreenshot(Display.DEFAULT_DISPLAY, mUserId); } verify(mMockImeTargetVisibilityPolicy).removeImeScreenshot(eq(Display.DEFAULT_DISPLAY)); |