diff options
| author | 2023-09-04 17:10:18 +0200 | |
|---|---|---|
| committer | 2023-09-06 08:33:54 +0000 | |
| commit | f883cdf3583bccb03b2a878df1365eb9b0137e41 (patch) | |
| tree | fb2113f1186b17a9c00333d7df6823d753cd0331 | |
| parent | 8aacb8172470090ff17ea81e405c22206117cf0f (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
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 { |