summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Cosmin Băieș <cosminbaies@google.com> 2023-09-04 17:10:18 +0200
committer Cosmin Băieș <cosminbaies@google.com> 2023-09-06 08:33:54 +0000
commitf883cdf3583bccb03b2a878df1365eb9b0137e41 (patch)
treefb2113f1186b17a9c00333d7df6823d753cd0331
parent8aacb8172470090ff17ea81e405c22206117cf0f (diff)
Check hasNavigationBar when showing IME nav bar
Before my CL [1] the IME navigation bar was directly tied to the System navigation bar, and would follow its visibility. Now that these two are untied, the IME navigation bar must check whether the System navigation bar will be drawn, to avoid showing itself when it shouldn't (e.g. emulator). Test: run on emulator, check that IME navigation bar is not shown; atest InputMethodServiceTest#testNoNavigationBar_thenImeNoCaptionBar Bug: 296435448 Merged-In: Ide89075836a527d806f28cbeeb8d90334b79428f Change-Id: Ide89075836a527d806f28cbeeb8d90334b79428f
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java20
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java20
2 files changed, 39 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6509126dcc60..3812dd60cd70 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -119,6 +119,7 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
+import android.view.IWindowManager;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -126,6 +127,7 @@ import android.view.WindowManager;
import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+import android.view.WindowManagerGlobal;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ImeTracker;
import android.view.inputmethod.InputBinding;
@@ -3072,7 +3074,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
"Waiting for the lazy init of mImeDrawsImeNavBarRes");
}
final boolean canImeDrawsImeNavBar =
- mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get();
+ mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get()
+ && hasNavigationBarOnCurrentDisplay();
final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(
InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE);
return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
@@ -3080,6 +3083,21 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
}
+ /**
+ * Whether the current display has a navigation bar. When this is {@code false} (e.g. emulator),
+ * the IME should <em>not</em> draw the IME navigation bar.
+ */
+ @GuardedBy("ImfLock.class")
+ private boolean hasNavigationBarOnCurrentDisplay() {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ try {
+ return wm.hasNavigationBar(mCurTokenDisplayId != INVALID_DISPLAY
+ ? mCurTokenDisplayId : DEFAULT_DISPLAY);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
@GuardedBy("ImfLock.class")
private boolean shouldShowImeSwitcherLocked(int visibility) {
if (!mShowOngoingImeSwitcherForPhones) return false;
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index e8acb067f625..6ff7b2601b79 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -16,15 +16,20 @@
package com.android.inputmethodservice;
+import static android.view.WindowInsets.Type.captionBar;
+
import static com.android.compatibility.common.util.SystemUtil.eventually;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Insets;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.uiautomator.By;
@@ -32,6 +37,7 @@ import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.util.Log;
+import android.view.WindowManagerGlobal;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
@@ -592,6 +598,20 @@ public class InputMethodServiceTest {
false /* orientationPortrait */);
}
+ /**
+ * This checks that when the system navigation bar is not created (e.g. emulator),
+ * then the IME caption bar is also not created.
+ */
+ @Test
+ public void testNoNavigationBar_thenImeNoCaptionBar() throws Exception {
+ boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService()
+ .hasNavigationBar(mInputMethodService.getDisplayId());
+ assumeFalse("Must not have a navigation bar", hasNavigationBar);
+
+ assertEquals(Insets.NONE, mInputMethodService.getWindow().getWindow().getDecorView()
+ .getRootWindowInsets().getInsetsIgnoringVisibility(captionBar()));
+ }
+
private void verifyInputViewStatus(
Runnable runnable, boolean expected, boolean inputViewStarted)
throws InterruptedException {