Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d0b620c authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Use correct navigation hint for IME visibility

The system navigation bar and taskbar were correctly computing the
navigation hint flags, but using the incorrect flag
(navigation_hint_back_alt) to save the state of the IME visibility.

While this back_alt flag can only ever be set while the IME is visible,
it can also be unset when the IME is visible. In practice, any IME can
override this to be unset while the IME is visible, and the system also
temporarily overrides it while the IME Switcher menu is visible. This
would lead to the navigation bar/taskbar incorrectly beliving the IME is
not visible.

Additionally renames onImeVisibilityChanged (introduced in [1]) to
onBackAltChanged, to reflect the original meaning from [2].

This fixes the IME visibility state to be computed based on the
navigation_hint_ime_shown flag.

  [1]: I6034d66532d83d7f12b5e7d65610d4aa91b3533f
  [2]: Ifd1f8c9f400d90542f0ca858b9a4deacabbd518a

Flag: EXEMPT bugfix
Bug: 366129400
Test: atest NavigationBarTest#testSetImeWindowStatusSysuiState_ImeVisibleImeSwitcherButtonVisible
  NavigationBarTest#testSetImeWindowStatusSysuiState_ImeVisibleImeSwitcherButtonNotVisible
  NavigationBarTest#testSetImeWindowStatusSysuiState_ImeNotVisibleImeSwitcherButtonVisible
  NavigationBarTest#testSetImeWindowStatusSysuiState_ImeVisibleBackDispositionAdjustNothing
Change-Id: Ic57cea49f5ff49132802083b4f0c9b0e82db1cf7
parent 80db1783
Loading
Loading
Loading
Loading
+12 −10
Original line number Original line Diff line number Diff line
@@ -16,6 +16,9 @@


package android.inputmethodservice;
package android.inputmethodservice;


import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;


@@ -23,7 +26,6 @@ import android.animation.ValueAnimator;
import android.annotation.FloatRange;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.StatusBarManager;
import android.graphics.Color;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Rect;
@@ -241,10 +243,9 @@ final class NavigationBarController {
                if (navigationBarView != null) {
                if (navigationBarView != null) {
                    // TODO(b/213337792): Support InputMethodService#setBackDisposition().
                    // TODO(b/213337792): Support InputMethodService#setBackDisposition().
                    // TODO(b/213337792): Set NAVIGATION_HINT_IME_SHOWN only when necessary.
                    // TODO(b/213337792): Set NAVIGATION_HINT_IME_SHOWN only when necessary.
                    final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
                    final int hints = NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
                            | (mShouldShowImeSwitcherWhenImeIsShown
                            | (mShouldShowImeSwitcherWhenImeIsShown
                                    ? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN
                                    ? NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
                                    : 0);
                    navigationBarView.setNavigationIconHints(hints);
                    navigationBarView.setNavigationIconHints(hints);
                    navigationBarView.prepareNavButtons(this);
                    navigationBarView.prepareNavButtons(this);
                }
                }
@@ -512,13 +513,14 @@ final class NavigationBarController {
                }
                }
                final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate(
                final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate(
                        NavigationBarView.class::isInstance);
                        NavigationBarView.class::isInstance);
                if (navigationBarView == null) {
                if (navigationBarView != null) {
                    return;
                    // TODO(b/213337792): Support InputMethodService#setBackDisposition().
                }
                    // TODO(b/213337792): Set NAVIGATION_HINT_IME_SHOWN only when necessary.
                final int hints = StatusBarManager.NAVIGATION_HINT_BACK_ALT
                    final int hints = NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
                        | (shouldShowImeSwitcherWhenImeIsShown
                            | (mShouldShowImeSwitcherWhenImeIsShown
                                ? StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
                                    ? NAVIGATION_HINT_IME_SWITCHER_SHOWN : 0);
                    navigationBarView.setNavigationIconHints(hints);
                    navigationBarView.setNavigationIconHints(hints);
                }
            } else {
            } else {
                uninstallNavigationBarFrameIfNecessary();
                uninstallNavigationBarFrameIfNecessary();
            }
            }
+1 −1
Original line number Original line Diff line number Diff line
@@ -290,7 +290,7 @@ public final class NavigationBarView extends FrameLayout {
        final boolean oldBackAlt =
        final boolean oldBackAlt =
                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
        if (newBackAlt != oldBackAlt) {
        if (newBackAlt != oldBackAlt) {
            //onImeVisibilityChanged(newBackAlt);
            //onBackAltChanged(newBackAlt);
        }
        }


        if (DEBUG) {
        if (DEBUG) {
+62 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.navigationbar.views;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_ADJUST_NOTHING;
import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -30,6 +31,8 @@ import static com.android.systemui.assist.AssistManager.INVOCATION_TYPE_HOME_BUT
import static com.android.systemui.navigationbar.views.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
import static com.android.systemui.navigationbar.views.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS;
import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_LONGPRESS;
import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP;
import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;


import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;
@@ -487,6 +490,65 @@ public class NavigationBarTest extends SysuiTestCase {
        verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class));
        verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class));
    }
    }


    /**
     * Verifies that the SysUI state is updated correctly when given a new IME window status with
     * IME visible and IME Switcher button visible.
     */
    @Test
    public void testSetImeWindowStatusSysuiState_ImeVisibleImeSwitcherButtonVisible() {
        doNothing().when(mNavigationBar).checkNavBarModes();

        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, IME_VISIBLE,
                BACK_DISPOSITION_DEFAULT, true /* showImeSwitcher */);
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SHOWING), eq(true));
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SWITCHER_SHOWING), eq(true));
    }

    /**
     * Verifies that the SysUI state is updated correctly when given a new IME window status with
     * IME visible and IME Switcher button not visible.
     */
    @Test
    public void testSetImeWindowStatusSysuiState_ImeVisibleImeSwitcherButtonNotVisible() {
        doNothing().when(mNavigationBar).checkNavBarModes();

        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, IME_VISIBLE,
                BACK_DISPOSITION_DEFAULT, false /* showImeSwitcher */);
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SHOWING), eq(true));
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SWITCHER_SHOWING), eq(false));
    }

    /**
     * Verifies that the SysUI state is updated correctly when given a new IME window status with
     * IME not visible and IME Switcher button visible.
     */
    @Test
    public void testSetImeWindowStatusSysuiState_ImeNotVisibleImeSwitcherButtonVisible() {
        doNothing().when(mNavigationBar).checkNavBarModes();
        // Set initial state for later reset to be able to take place.
        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, IME_VISIBLE,
                BACK_DISPOSITION_DEFAULT, true /* showImeSwitcher */);

        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, 0 /* vis */,
                BACK_DISPOSITION_DEFAULT, true /* showImeSwitcher */);
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SHOWING), eq(false));
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SWITCHER_SHOWING), eq(false));
    }

    /**
     * Verifies that the SysUI state is updated correctly when given a new IME window status with
     * IME visible and back disposition adjust nothing.
     */
    @Test
    public void testSetImeWindowStatusSysuiState_ImeVisibleBackDispositionAdjustNothing() {
        doNothing().when(mNavigationBar).checkNavBarModes();

        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, IME_VISIBLE,
                BACK_DISPOSITION_ADJUST_NOTHING, true /* showImeSwitcher */);
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SHOWING), eq(true));
        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_IME_SWITCHER_SHOWING), eq(true));
    }

    @Test
    @Test
    public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
    public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
        // Create default & external NavBar fragment.
        // Create default & external NavBar fragment.
+2 −2
Original line number Original line Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.systemui.navigationbar;
package com.android.systemui.navigationbar;


import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
@@ -336,7 +336,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
        mSysUiState.setFlag(SYSUI_STATE_A11Y_BUTTON_CLICKABLE, clickable)
        mSysUiState.setFlag(SYSUI_STATE_A11Y_BUTTON_CLICKABLE, clickable)
                .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
                .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
                .setFlag(SYSUI_STATE_IME_SHOWING,
                .setFlag(SYSUI_STATE_IME_SHOWING,
                        (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
                        (mNavigationIconHints & NAVIGATION_HINT_IME_SHOWN) != 0)
                .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
                .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
                        (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
                        (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
                .setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
                .setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
+4 −4
Original line number Original line Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.systemui.navigationbar.views;
package com.android.systemui.navigationbar.views;


import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
@@ -1681,7 +1681,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
                .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
                .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
                .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible())
                .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible())
                .setFlag(SYSUI_STATE_IME_SHOWING,
                .setFlag(SYSUI_STATE_IME_SHOWING,
                        (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
                        (mNavigationIconHints & NAVIGATION_HINT_IME_SHOWN) != 0)
                .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
                .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
                        (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
                        (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
                .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
                .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
@@ -1939,9 +1939,9 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
            final boolean oldBackAlt =
            final boolean oldBackAlt =
                    (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
                    (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
            if (newBackAlt != oldBackAlt) {
            if (newBackAlt != oldBackAlt) {
                mView.onImeVisibilityChanged(newBackAlt);
                mView.onBackAltChanged(newBackAlt);
                mImeVisible = newBackAlt;
            }
            }
            mImeVisible = (hints & NAVIGATION_HINT_IME_SHOWN) != 0;


            mView.setNavigationIconHints(hints);
            mView.setNavigationIconHints(hints);
        }
        }
Loading