Fix some issues in FrameworkInputMethodSystemServerTests
- Fix wrong src path in InputMethodSystemServerTests/Android.bp by CL[1]
- In IMMS, Make ImeTrackerService by CL[2] can inject a test looper, in
case InputMethodManagerServiceTestBase#setUp got exception by null
looper queue.
- Remove unused test method IMMS#getVisibilityStateComputer().
- Add ImfLock block in IMMS#getVisibilityApplier for fixing linter
check.
- Fix a potential NPE when calling mImeTrackerService.onImmsUpdate that
the statsToken may null during testing.
- Remove duplicate calls in testApplyImeVisibility_throwForInvalidState.
- Add missed showFlag parameters in testPerformShowIme.
- Fix verifyShowSoftInput logic when no need to verify showFlags cases
- Add a regression unit test In ImeVisibilityStateComputerTest for
Bug 265439883:
testComputeState_lastImeRequestedVisible_preserved_When_StateUnChanged
[1]: I84f1a1b25eef4a757d8da27807285e08417458b4
[2]: I432bab2de58a9df2c421bb00946ab211de445660
Bug: 246309664
Bug: 240359838
Test: atest FrameworkInputMethodSystemServerTests all passed
Change-Id: I0890641868f9200c613af0d6ee7014e4c7b1e7ed
diff --git a/services/core/java/com/android/server/inputmethod/ImeTrackerService.java b/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
index 60167b4..da65f27 100644
--- a/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
+++ b/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
@@ -59,13 +59,16 @@
private static final long TIMEOUT_MS = 10_000;
/** Handler for registering timeouts for live entries. */
- private final Handler mHandler =
- new Handler(Looper.myLooper(), null /* callback */, true /* async */);
+ private final Handler mHandler;
/** Singleton instance of the History. */
@GuardedBy("ImeTrackerService.this")
private final History mHistory = new History();
+ ImeTrackerService(@NonNull Looper looper) {
+ mHandler = new Handler(looper, null /* callback */, true /* async */);
+ }
+
@NonNull
@Override
public synchronized IBinder onRequestShow(int uid, @ImeTracker.Origin int origin,
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 19108a8..9899719 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -89,6 +89,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.LocaleList;
+import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.Process;
@@ -1105,7 +1106,7 @@
new SoftInputShowHideHistory();
@NonNull
- private final ImeTrackerService mImeTrackerService = new ImeTrackerService();
+ private final ImeTrackerService mImeTrackerService;
class SettingsObserver extends ContentObserver {
int mUserId;
@@ -1662,6 +1663,8 @@
true /* allowIo */);
thread.start();
mHandler = Handler.createAsync(thread.getLooper(), this);
+ mImeTrackerService = new ImeTrackerService(serviceThreadForTesting != null
+ ? serviceThreadForTesting.getLooper() : Looper.getMainLooper());
// Note: SettingsObserver doesn't register observers in its constructor.
mSettingsObserver = new SettingsObserver(mHandler);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
@@ -4612,7 +4615,9 @@
info.requestWindowName, info.imeControlTargetName, info.imeLayerTargetName,
info.imeSurfaceParentName));
- mImeTrackerService.onImmsUpdate(statsToken.mBinder, info.requestWindowName);
+ if (statsToken != null) {
+ mImeTrackerService.onImmsUpdate(statsToken.mBinder, info.requestWindowName);
+ }
}
@BinderThread
@@ -4654,13 +4659,10 @@
}
@VisibleForTesting
- ImeVisibilityStateComputer getVisibilityStateComputer() {
- return mVisibilityStateComputer;
- }
-
- @VisibleForTesting
ImeVisibilityApplier getVisibilityApplier() {
- return mVisibilityApplier;
+ synchronized (ImfLock.class) {
+ return mVisibilityApplier;
+ }
}
@GuardedBy("ImfLock.class")
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 70a5c3f..05a8b11 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -28,7 +28,7 @@
],
srcs: [
- "src/server/**/*.java",
+ "src/com/android/server/inputmethod/**/*.java",
],
static_libs: [
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 73d04c6..720f486 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
@@ -65,19 +65,24 @@
@Test
public void testPerformShowIme() throws Exception {
- mVisibilityApplier.performShowIme(mWindowToken, null, null, SHOW_SOFT_INPUT);
+ synchronized (ImfLock.class) {
+ mVisibilityApplier.performShowIme(mWindowToken, null /* statsToken */,
+ InputMethodManager.SHOW_IMPLICIT, null, SHOW_SOFT_INPUT);
+ }
verifyShowSoftInput(false, true, InputMethodManager.SHOW_IMPLICIT);
}
@Test
public void testPerformHideIme() throws Exception {
- mVisibilityApplier.performHideIme(mWindowToken, null, null, HIDE_SOFT_INPUT);
+ synchronized (ImfLock.class) {
+ mVisibilityApplier.performHideIme(mWindowToken, null /* statsToken */, null,
+ HIDE_SOFT_INPUT);
+ }
verifyHideSoftInput(false, true);
}
@Test
public void testApplyImeVisibility_throwForInvalidState() {
- mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_INVALID);
assertThrows(IllegalArgumentException.class,
() -> mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_INVALID));
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
index 8415fe1..a1b9b98 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
@@ -30,6 +30,7 @@
import static com.google.common.truth.Truth.assertThat;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.inputmethod.InputMethodManager;
@@ -177,9 +178,28 @@
assertThat(state.getImeDisplayId()).isEqualTo(FALLBACK_DISPLAY_ID);
}
- private void initImeTargetWindowState(IBinder windowToken) {
+ @Test
+ public void testComputeState_lastImeRequestedVisible_preserved_When_StateUnChanged() {
+ // Assume the last IME targeted window has requested IME visible
+ final IBinder lastImeTargetWindowToken = new Binder();
+ mInputMethodManagerService.mLastImeTargetWindow = lastImeTargetWindowToken;
+ mComputer.requestImeVisibility(lastImeTargetWindowToken, true);
+ final ImeTargetWindowState lastState = mComputer.getWindowStateOrNull(
+ lastImeTargetWindowToken);
+ assertThat(lastState.isRequestedImeVisible()).isTrue();
+
+ // Verify when focusing the next window with STATE_UNCHANGED flag, the last IME
+ // visibility state will be preserved to the current window state.
+ final ImeTargetWindowState stateWithUnChangedFlag = initImeTargetWindowState(mWindowToken);
+ mComputer.computeState(stateWithUnChangedFlag, true /* allowVisible */);
+ assertThat(stateWithUnChangedFlag.isRequestedImeVisible()).isEqualTo(
+ lastState.isRequestedImeVisible());
+ }
+
+ private ImeTargetWindowState initImeTargetWindowState(IBinder windowToken) {
final ImeTargetWindowState state = new ImeTargetWindowState(SOFT_INPUT_STATE_UNCHANGED,
0, true, true, true);
mComputer.setWindowState(windowToken, state);
+ return state;
}
}
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 804bb49..dbdffd0 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -71,6 +71,8 @@
/** Base class for testing {@link InputMethodManagerService}. */
public class InputMethodManagerServiceTestBase {
+ private static final int NO_VERIFY_SHOW_FLAGS = -1;
+
protected static final String TEST_SELECTED_IME_ID = "test.ime";
protected static final String TEST_EDITOR_PKG_NAME = "test.editor";
protected static final String TEST_FOCUSED_WINDOW_NAME = "test.editor/activity";
@@ -239,7 +241,7 @@
protected void verifyShowSoftInput(boolean setVisible, boolean showSoftInput)
throws RemoteException {
- verifyShowSoftInput(setVisible, showSoftInput, anyInt());
+ verifyShowSoftInput(setVisible, showSoftInput, NO_VERIFY_SHOW_FLAGS);
}
protected void verifyShowSoftInput(boolean setVisible, boolean showSoftInput, int showFlags)
@@ -249,7 +251,8 @@
.setCurrentMethodVisible();
}
verify(mMockInputMethod, times(showSoftInput ? 1 : 0))
- .showSoftInput(any(), any(), eq(showFlags), any());
+ .showSoftInput(any(), any(),
+ showFlags != NO_VERIFY_SHOW_FLAGS ? eq(showFlags) : anyInt(), any());
}
protected void verifyHideSoftInput(boolean setNotVisible, boolean hideSoftInput)