summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ming-Shin Lu <lumark@google.com> 2023-03-16 01:04:24 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-03-16 01:04:24 +0000
commit263ab0dd8f8f7f6e5e5fd221b4049eaeb330b418 (patch)
treeabb537b8a05e20fc51d1c38d99c42a2540801359
parent5bd81e3c6a25b1a8d612b2e454810f233786c1eb (diff)
parent65bc122ee9364a75392bf547061240caadd646d8 (diff)
Merge "ImeVisibilityApplier: fix hideIme no-op for Embedded display case." into udc-dev
-rw-r--r--services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java9
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java13
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java4
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java44
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 */);
+ }
}