diff options
| author | 2023-03-16 01:04:24 +0000 | |
|---|---|---|
| committer | 2023-03-16 01:04:24 +0000 | |
| commit | 263ab0dd8f8f7f6e5e5fd221b4049eaeb330b418 (patch) | |
| tree | abb537b8a05e20fc51d1c38d99c42a2540801359 | |
| parent | 5bd81e3c6a25b1a8d612b2e454810f233786c1eb (diff) | |
| parent | 65bc122ee9364a75392bf547061240caadd646d8 (diff) | |
Merge "ImeVisibilityApplier: fix hideIme no-op for Embedded display case." into udc-dev
4 files changed, 61 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java index 9f7ff3119dde..0ae1e8076b81 100644 --- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java +++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java @@ -136,17 +136,16 @@ final class DefaultImeVisibilityApplier implements ImeVisibilityApplier { mWindowManagerInternal.showImePostLayout(windowToken, statsToken); break; case STATE_HIDE_IME: - if (mService.mCurFocusedWindowClient != null) { + if (mService.hasAttachedClient()) { ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY); // IMMS only knows of focused window, not the actual IME target. // e.g. it isn't aware of any window that has both // NOT_FOCUSABLE, ALT_FOCUSABLE_IM flags set and can the IME target. - // Send it to window manager to hide IME from IME target window. - // TODO(b/139861270): send to mCurClient.client once IMMS is aware of - // actual IME target. + // Send it to window manager to hide IME from the actual IME control target + // of the target display. mWindowManagerInternal.hideIme(windowToken, - mService.mCurFocusedWindowClient.mSelfReportedDisplayId, statsToken); + mService.getDisplayIdToShowImeLocked(), statsToken); } else { ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index e32bf1beb300..b336b95d793f 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2339,6 +2339,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } + /** {@code true} when a {@link ClientState} has attached from starting the input connection. */ + @GuardedBy("ImfLock.class") + boolean hasAttachedClient() { + return mCurClient != null; + } + + @VisibleForTesting + void setAttachedClientForTesting(@NonNull ClientState cs) { + synchronized (ImfLock.class) { + mCurClient = cs; + } + } + @GuardedBy("ImfLock.class") void clearInputShownLocked() { mVisibilityStateComputer.setInputShown(false); diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 2f3a70eb0e2d..969afe544b18 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -740,7 +740,7 @@ public abstract class WindowManagerInternal { /** * Show IME on imeTargetWindow once IME has finished layout. * - * @param imeTargetWindowToken token of the (IME target) window on which IME should be shown. + * @param imeTargetWindowToken token of the (IME target) window which IME should be shown. * @param statsToken the token tracking the current IME show request or {@code null} otherwise. */ public abstract void showImePostLayout(IBinder imeTargetWindowToken, @@ -749,7 +749,7 @@ public abstract class WindowManagerInternal { /** * Hide IME using imeTargetWindow when requested. * - * @param imeTargetWindowToken token of the (IME target) window on which IME should be hidden. + * @param imeTargetWindowToken token of the (IME target) window on which requests hiding IME. * @param displayId the id of the display the IME is on. * @param statsToken the token tracking the current IME hide request or {@code null} otherwise. */ 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 7e440494a1e4..7d4f87d73507 100644 --- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java +++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java @@ -17,6 +17,7 @@ package com.android.server.inputmethod; import static android.inputmethodservice.InputMethodService.IME_ACTIVE; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE; import static com.android.internal.inputmethod.SoftInputShowHideReason.HIDE_SOFT_INPUT; import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_SOFT_INPUT; @@ -35,11 +36,16 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.os.Binder; +import android.os.IBinder; import android.os.RemoteException; import android.view.inputmethod.InputMethodManager; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.internal.inputmethod.InputBindResult; +import com.android.internal.inputmethod.StartInputFlags; +import com.android.internal.inputmethod.StartInputReason; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -60,8 +66,8 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe super.setUp(); mVisibilityApplier = (DefaultImeVisibilityApplier) mInputMethodManagerService.getVisibilityApplier(); - mInputMethodManagerService.mCurFocusedWindowClient = mock( - InputMethodManagerService.ClientState.class); + mInputMethodManagerService.setAttachedClientForTesting( + mock(InputMethodManagerService.ClientState.class)); } @Test @@ -119,4 +125,38 @@ public class DefaultImeVisibilityApplierTest extends InputMethodManagerServiceTe mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_SHOW_IME_IMPLICIT); verifyShowSoftInput(true, true, InputMethodManager.SHOW_IMPLICIT); } + + @Test + public void testApplyImeVisibility_hideImeFromTargetOnSecondaryDisplay() { + // Init a IME target client on the secondary display to show IME. + mInputMethodManagerService.addClient(mMockInputMethodClient, mMockRemoteInputConnection, + 10 /* selfReportedDisplayId */); + mInputMethodManagerService.setAttachedClientForTesting(null); + startInputOrWindowGainedFocus(mWindowToken, SOFT_INPUT_STATE_ALWAYS_VISIBLE); + + synchronized (ImfLock.class) { + final int displayIdToShowIme = mInputMethodManagerService.getDisplayIdToShowImeLocked(); + // Verify hideIme will apply the expected displayId when the default IME + // visibility applier app STATE_HIDE_IME. + mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_HIDE_IME); + verify(mInputMethodManagerService.mWindowManagerInternal).hideIme( + eq(mWindowToken), eq(displayIdToShowIme), eq(null)); + } + } + + private InputBindResult startInputOrWindowGainedFocus(IBinder windowToken, int softInputMode) { + return mInputMethodManagerService.startInputOrWindowGainedFocus( + StartInputReason.WINDOW_FOCUS_GAIN /* startInputReason */, + mMockInputMethodClient /* client */, + windowToken /* windowToken */, + StartInputFlags.VIEW_HAS_FOCUS | StartInputFlags.IS_TEXT_EDITOR, + softInputMode /* softInputMode */, + 0 /* windowFlags */, + mEditorInfo /* editorInfo */, + mMockRemoteInputConnection /* inputConnection */, + mMockRemoteAccessibilityInputConnection /* remoteAccessibilityInputConnection */, + mTargetSdkVersion /* unverifiedTargetSdkVersion */, + mCallingUserId /* userId */, + mMockImeOnBackInvokedDispatcher /* imeDispatcher */); + } } |