Loading core/java/android/inputmethodservice/InputMethodService.java +41 −18 Original line number Diff line number Diff line Loading @@ -434,6 +434,11 @@ public class InputMethodService extends AbstractInputMethodService { return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true); } /** * Cached value of {@link #canImeRenderGesturalNavButtons}, as it doesn't change at runtime. */ private final boolean mCanImeRenderGesturalNavButtons = canImeRenderGesturalNavButtons(); /** * Allows the system to optimize the back button affordance based on the presence of software * keyboard. Loading Loading @@ -564,6 +569,9 @@ public class InputMethodService extends AbstractInputMethodService { private final NavigationBarController mNavigationBarController = new NavigationBarController(this); /** Whether a custom IME Switcher button was requested to be visible. */ private boolean mCustomImeSwitcherButtonRequestedVisible; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; Loading Loading @@ -783,7 +791,7 @@ public class InputMethodService extends AbstractInputMethodService { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); mPrivOps.set(params.privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(params.token, mPrivOps); mNavigationBarController.onNavButtonFlagsChanged(params.navigationBarFlags); onNavButtonFlagsChanged(params.navigationBarFlags); attachToken(params.token); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } Loading Loading @@ -893,7 +901,7 @@ public class InputMethodService extends AbstractInputMethodService { public final void dispatchStartInput(@Nullable InputConnection inputConnection, @NonNull IInputMethod.StartInputParams params) { mPrivOps.reportStartInputAsync(params.startInputToken); mNavigationBarController.onNavButtonFlagsChanged(params.navigationBarFlags); onNavButtonFlagsChanged(params.navigationBarFlags); if (params.restarting) { restartInput(inputConnection, params.editorInfo); } else { Loading @@ -918,6 +926,20 @@ public class InputMethodService extends AbstractInputMethodService { @Override public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) { mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags); if (!mCanImeRenderGesturalNavButtons) { final boolean showImeSwitcher = (navButtonFlags & InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN) != 0; // The IME cannot draw the IME nav bar, so this will never be visible. In this case // the system nav bar hosts the IME buttons. // The system nav bar will be hidden when the IME is shown and the config is set. final boolean navBarNotVisible = getApplicationContext().getResources() .getBoolean(com.android.internal.R.bool.config_hideNavBarForKeyboard); final boolean visible = showImeSwitcher && navBarNotVisible; if (visible != mCustomImeSwitcherButtonRequestedVisible) { mCustomImeSwitcherButtonRequestedVisible = visible; onCustomImeSwitcherButtonRequestedVisible(visible); } } } /** Loading Loading @@ -4473,28 +4495,27 @@ public class InputMethodService extends AbstractInputMethodService { /** * Called when the requested visibility of a custom IME Switcher button changes. * * <p>When the system provides an IME navigation bar, it may decide to show an IME Switcher * button inside this bar. However, the IME can request hiding the bar provided by the system * with {@code getWindowInsetsController().hide(captionBar())} (the IME navigation bar provides * {@link Type#captionBar() captionBar} insets to the IME window). If the request is successful, * then it becomes the IME's responsibility to provide a custom IME Switcher button in its * input view, with equivalent functionality.</p> * <p>When this method is called with {@code true} by the system, the IME must show a button * within its UI to switch IMEs. When it is called with {@code false}, it must hide this button. * * <p>Normally, the system provides a button for switching to a different IME when that is * appropriate. Under certain circumstances, namely when the IME successfully asks to hide the * system-provided navigation bar (with {@code getWindowInsetsController().hide(captionBar())}), * providing this button is delegated to the IME through this callback. * * <p>This custom button is only requested to be visible when the system provides the IME * navigation bar, both the bar and the IME Switcher button inside it should be visible, * but the IME successfully requested to hide the bar. This does not depend on the current * visibility of the IME. It could be called with {@code true} while the IME is hidden, in * which case the IME should prepare to show the button as soon as the IME itself is shown.</p> * <p>This does not depend on the current visibility of the IME. It could be called with * {@code true} while the IME is hidden, in which case the IME should prepare to show the button * as soon as the IME itself is shown. * * <p>This is only called when the requested visibility changes. The default value is * {@code false} and as such, this will not be called initially if the resulting value is * {@code false}.</p> * {@code false}. * * <p>This can be called at any time after {@link #onCreate}, even if the IME is not currently * visible. However, this is not guaranteed to be called before the IME is shown, as it depends * on when the IME requested hiding the IME navigation bar. If the request is sent during * the showing flow (e.g. during {@link #onStartInputView}), this will be called shortly after * {@link #onWindowShown}, but before the first IME frame is drawn.</p> * visible. However, this is not guaranteed to be called before the IME is shown, as it may * depend on the IME requesting to hide the system-provided navigation bar. If the request is * sent during the showing flow (e.g. during {@link #onStartInputView}), this will be called * shortly after {@link #onWindowShown}, but before the first IME frame is drawn. * * @param visible whether the button is requested visible or not. */ Loading Loading @@ -4686,6 +4707,8 @@ public class InputMethodService extends AbstractInputMethodService { + " touchableRegion=" + mTmpInsets.touchableRegion); p.println(" mSettingsObserver=" + mSettingsObserver); p.println(" mNavigationBarController=" + mNavigationBarController.toDebugString()); p.println(" mCustomImeSwitcherButtonRequestedVisible=" + mCustomImeSwitcherButtonRequestedVisible); } private final ImeTracing.ServiceDumper mDumper = new ImeTracing.ServiceDumper() { Loading core/java/android/inputmethodservice/NavigationBarController.java +42 −34 Original line number Diff line number Diff line Loading @@ -170,6 +170,9 @@ final class NavigationBarController { private boolean mShouldShowImeSwitcherWhenImeIsShown; /** Whether a custom IME Switcher button should be visible. */ private boolean mCustomImeSwitcherButtonRequestedVisible; @Appearance private int mAppearance; Loading @@ -181,9 +184,6 @@ final class NavigationBarController { private boolean mDrawLegacyNavigationBarBackground; /** Whether a custom IME Switcher button should be visible. */ private boolean mCustomImeSwitcherVisible; private final Rect mTempRect = new Rect(); private final int[] mTempPos = new int[2]; Loading Loading @@ -275,7 +275,9 @@ final class NavigationBarController { // IME navigation bar. boolean visible = insets.isVisible(captionBar()); mNavigationBarFrame.setVisibility(visible ? View.VISIBLE : View.GONE); checkCustomImeSwitcherVisibility(); checkCustomImeSwitcherButtonRequestedVisible( mShouldShowImeSwitcherWhenImeIsShown, mImeDrawsImeNavBar, !visible /* imeNavBarNotVisible */); } return view.onApplyWindowInsets(insets); }); Loading Loading @@ -502,22 +504,15 @@ final class NavigationBarController { mShouldShowImeSwitcherWhenImeIsShown; mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown; checkCustomImeSwitcherVisibility(); mService.mWindow.getWindow().getDecorView().getWindowInsetsController() .setImeCaptionBarInsetsHeight(getImeCaptionBarHeight(imeDrawsImeNavBar)); if (imeDrawsImeNavBar) { installNavigationBarFrameIfNecessary(); if (mNavigationBarFrame == null) { return; } if (mShouldShowImeSwitcherWhenImeIsShown == prevShouldShowImeSwitcherWhenImeIsShown) { return; } final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate( NavigationBarView.class::isInstance); if (mNavigationBarFrame != null && mShouldShowImeSwitcherWhenImeIsShown != prevShouldShowImeSwitcherWhenImeIsShown) { final NavigationBarView navigationBarView = mNavigationBarFrame .findViewByPredicate(NavigationBarView.class::isInstance); if (navigationBarView != null) { // TODO(b/213337792): Support InputMethodService#setBackDisposition(). // TODO(b/213337792): Set NAVBAR_IME_VISIBLE only when necessary. Loading @@ -526,9 +521,14 @@ final class NavigationBarController { ? NAVBAR_IME_SWITCHER_BUTTON_VISIBLE : 0); navigationBarView.setNavbarFlags(flags); } } } else { uninstallNavigationBarFrameIfNecessary(); } // Check custom IME Switcher button visibility after (un)installing nav bar frame. checkCustomImeSwitcherButtonRequestedVisible(shouldShowImeSwitcherWhenImeIsShown, imeDrawsImeNavBar, !isShown() /* imeNavBarNotVisible */); } @Override Loading Loading @@ -631,22 +631,29 @@ final class NavigationBarController { } /** * Checks if a custom IME Switcher button should be visible, and notifies the IME when this * state changes. This can only be {@code true} if three conditions are met: * Checks if a custom IME Switcher button should be requested visible, and notifies the IME * when this state changes. This is only {@code true} when the IME Switcher button is * requested visible, and the navigation bar is not requested visible. * * <li>The IME should draw the IME navigation bar.</li> * <li>The IME Switcher button should be visible when the IME is visible.</li> * <li>The IME navigation bar should be visible, but was requested hidden by the IME.</li> * @param buttonVisible whether the IME Switcher button is requested visible. * @param shouldDrawImeNavBar whether the IME navigation bar should be drawn. * @param imeNavBarNotVisible whether the IME navigation bar is not requested visible. This * will be {@code true} if it is requested hidden or not * installed. */ private void checkCustomImeSwitcherVisibility() { private void checkCustomImeSwitcherButtonRequestedVisible(boolean buttonVisible, boolean shouldDrawImeNavBar, boolean imeNavBarNotVisible) { if (!Flags.imeSwitcherRevampApi()) { return; } final boolean visible = mImeDrawsImeNavBar && mShouldShowImeSwitcherWhenImeIsShown && mNavigationBarFrame != null && !isShown(); if (visible != mCustomImeSwitcherVisible) { mCustomImeSwitcherVisible = visible; mService.onCustomImeSwitcherButtonRequestedVisible(mCustomImeSwitcherVisible); // The system nav bar will be hidden when the IME is shown and the config is set. final boolean navBarNotVisible = shouldDrawImeNavBar ? imeNavBarNotVisible : mService.getResources().getBoolean( com.android.internal.R.bool.config_hideNavBarForKeyboard); final boolean visible = buttonVisible && navBarNotVisible; if (visible != mCustomImeSwitcherButtonRequestedVisible) { mCustomImeSwitcherButtonRequestedVisible = visible; mService.onCustomImeSwitcherButtonRequestedVisible(visible); } } Loading @@ -656,7 +663,8 @@ final class NavigationBarController { + " mNavigationBarFrame=" + mNavigationBarFrame + " mShouldShowImeSwitcherWhenImeIsShown=" + mShouldShowImeSwitcherWhenImeIsShown + " mCustomImeSwitcherVisible=" + mCustomImeSwitcherVisible + " mCustomImeSwitcherButtonRequestedVisible=" + mCustomImeSwitcherButtonRequestedVisible + " mAppearance=0x" + Integer.toHexString(mAppearance) + " mDarkIntensity=" + mDarkIntensity + " mDrawLegacyNavigationBarBackground=" + mDrawLegacyNavigationBarBackground Loading Loading
core/java/android/inputmethodservice/InputMethodService.java +41 −18 Original line number Diff line number Diff line Loading @@ -434,6 +434,11 @@ public class InputMethodService extends AbstractInputMethodService { return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true); } /** * Cached value of {@link #canImeRenderGesturalNavButtons}, as it doesn't change at runtime. */ private final boolean mCanImeRenderGesturalNavButtons = canImeRenderGesturalNavButtons(); /** * Allows the system to optimize the back button affordance based on the presence of software * keyboard. Loading Loading @@ -564,6 +569,9 @@ public class InputMethodService extends AbstractInputMethodService { private final NavigationBarController mNavigationBarController = new NavigationBarController(this); /** Whether a custom IME Switcher button was requested to be visible. */ private boolean mCustomImeSwitcherButtonRequestedVisible; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; Loading Loading @@ -783,7 +791,7 @@ public class InputMethodService extends AbstractInputMethodService { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal"); mPrivOps.set(params.privilegedOperations); InputMethodPrivilegedOperationsRegistry.put(params.token, mPrivOps); mNavigationBarController.onNavButtonFlagsChanged(params.navigationBarFlags); onNavButtonFlagsChanged(params.navigationBarFlags); attachToken(params.token); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } Loading Loading @@ -893,7 +901,7 @@ public class InputMethodService extends AbstractInputMethodService { public final void dispatchStartInput(@Nullable InputConnection inputConnection, @NonNull IInputMethod.StartInputParams params) { mPrivOps.reportStartInputAsync(params.startInputToken); mNavigationBarController.onNavButtonFlagsChanged(params.navigationBarFlags); onNavButtonFlagsChanged(params.navigationBarFlags); if (params.restarting) { restartInput(inputConnection, params.editorInfo); } else { Loading @@ -918,6 +926,20 @@ public class InputMethodService extends AbstractInputMethodService { @Override public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) { mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags); if (!mCanImeRenderGesturalNavButtons) { final boolean showImeSwitcher = (navButtonFlags & InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN) != 0; // The IME cannot draw the IME nav bar, so this will never be visible. In this case // the system nav bar hosts the IME buttons. // The system nav bar will be hidden when the IME is shown and the config is set. final boolean navBarNotVisible = getApplicationContext().getResources() .getBoolean(com.android.internal.R.bool.config_hideNavBarForKeyboard); final boolean visible = showImeSwitcher && navBarNotVisible; if (visible != mCustomImeSwitcherButtonRequestedVisible) { mCustomImeSwitcherButtonRequestedVisible = visible; onCustomImeSwitcherButtonRequestedVisible(visible); } } } /** Loading Loading @@ -4473,28 +4495,27 @@ public class InputMethodService extends AbstractInputMethodService { /** * Called when the requested visibility of a custom IME Switcher button changes. * * <p>When the system provides an IME navigation bar, it may decide to show an IME Switcher * button inside this bar. However, the IME can request hiding the bar provided by the system * with {@code getWindowInsetsController().hide(captionBar())} (the IME navigation bar provides * {@link Type#captionBar() captionBar} insets to the IME window). If the request is successful, * then it becomes the IME's responsibility to provide a custom IME Switcher button in its * input view, with equivalent functionality.</p> * <p>When this method is called with {@code true} by the system, the IME must show a button * within its UI to switch IMEs. When it is called with {@code false}, it must hide this button. * * <p>Normally, the system provides a button for switching to a different IME when that is * appropriate. Under certain circumstances, namely when the IME successfully asks to hide the * system-provided navigation bar (with {@code getWindowInsetsController().hide(captionBar())}), * providing this button is delegated to the IME through this callback. * * <p>This custom button is only requested to be visible when the system provides the IME * navigation bar, both the bar and the IME Switcher button inside it should be visible, * but the IME successfully requested to hide the bar. This does not depend on the current * visibility of the IME. It could be called with {@code true} while the IME is hidden, in * which case the IME should prepare to show the button as soon as the IME itself is shown.</p> * <p>This does not depend on the current visibility of the IME. It could be called with * {@code true} while the IME is hidden, in which case the IME should prepare to show the button * as soon as the IME itself is shown. * * <p>This is only called when the requested visibility changes. The default value is * {@code false} and as such, this will not be called initially if the resulting value is * {@code false}.</p> * {@code false}. * * <p>This can be called at any time after {@link #onCreate}, even if the IME is not currently * visible. However, this is not guaranteed to be called before the IME is shown, as it depends * on when the IME requested hiding the IME navigation bar. If the request is sent during * the showing flow (e.g. during {@link #onStartInputView}), this will be called shortly after * {@link #onWindowShown}, but before the first IME frame is drawn.</p> * visible. However, this is not guaranteed to be called before the IME is shown, as it may * depend on the IME requesting to hide the system-provided navigation bar. If the request is * sent during the showing flow (e.g. during {@link #onStartInputView}), this will be called * shortly after {@link #onWindowShown}, but before the first IME frame is drawn. * * @param visible whether the button is requested visible or not. */ Loading Loading @@ -4686,6 +4707,8 @@ public class InputMethodService extends AbstractInputMethodService { + " touchableRegion=" + mTmpInsets.touchableRegion); p.println(" mSettingsObserver=" + mSettingsObserver); p.println(" mNavigationBarController=" + mNavigationBarController.toDebugString()); p.println(" mCustomImeSwitcherButtonRequestedVisible=" + mCustomImeSwitcherButtonRequestedVisible); } private final ImeTracing.ServiceDumper mDumper = new ImeTracing.ServiceDumper() { Loading
core/java/android/inputmethodservice/NavigationBarController.java +42 −34 Original line number Diff line number Diff line Loading @@ -170,6 +170,9 @@ final class NavigationBarController { private boolean mShouldShowImeSwitcherWhenImeIsShown; /** Whether a custom IME Switcher button should be visible. */ private boolean mCustomImeSwitcherButtonRequestedVisible; @Appearance private int mAppearance; Loading @@ -181,9 +184,6 @@ final class NavigationBarController { private boolean mDrawLegacyNavigationBarBackground; /** Whether a custom IME Switcher button should be visible. */ private boolean mCustomImeSwitcherVisible; private final Rect mTempRect = new Rect(); private final int[] mTempPos = new int[2]; Loading Loading @@ -275,7 +275,9 @@ final class NavigationBarController { // IME navigation bar. boolean visible = insets.isVisible(captionBar()); mNavigationBarFrame.setVisibility(visible ? View.VISIBLE : View.GONE); checkCustomImeSwitcherVisibility(); checkCustomImeSwitcherButtonRequestedVisible( mShouldShowImeSwitcherWhenImeIsShown, mImeDrawsImeNavBar, !visible /* imeNavBarNotVisible */); } return view.onApplyWindowInsets(insets); }); Loading Loading @@ -502,22 +504,15 @@ final class NavigationBarController { mShouldShowImeSwitcherWhenImeIsShown; mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown; checkCustomImeSwitcherVisibility(); mService.mWindow.getWindow().getDecorView().getWindowInsetsController() .setImeCaptionBarInsetsHeight(getImeCaptionBarHeight(imeDrawsImeNavBar)); if (imeDrawsImeNavBar) { installNavigationBarFrameIfNecessary(); if (mNavigationBarFrame == null) { return; } if (mShouldShowImeSwitcherWhenImeIsShown == prevShouldShowImeSwitcherWhenImeIsShown) { return; } final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate( NavigationBarView.class::isInstance); if (mNavigationBarFrame != null && mShouldShowImeSwitcherWhenImeIsShown != prevShouldShowImeSwitcherWhenImeIsShown) { final NavigationBarView navigationBarView = mNavigationBarFrame .findViewByPredicate(NavigationBarView.class::isInstance); if (navigationBarView != null) { // TODO(b/213337792): Support InputMethodService#setBackDisposition(). // TODO(b/213337792): Set NAVBAR_IME_VISIBLE only when necessary. Loading @@ -526,9 +521,14 @@ final class NavigationBarController { ? NAVBAR_IME_SWITCHER_BUTTON_VISIBLE : 0); navigationBarView.setNavbarFlags(flags); } } } else { uninstallNavigationBarFrameIfNecessary(); } // Check custom IME Switcher button visibility after (un)installing nav bar frame. checkCustomImeSwitcherButtonRequestedVisible(shouldShowImeSwitcherWhenImeIsShown, imeDrawsImeNavBar, !isShown() /* imeNavBarNotVisible */); } @Override Loading Loading @@ -631,22 +631,29 @@ final class NavigationBarController { } /** * Checks if a custom IME Switcher button should be visible, and notifies the IME when this * state changes. This can only be {@code true} if three conditions are met: * Checks if a custom IME Switcher button should be requested visible, and notifies the IME * when this state changes. This is only {@code true} when the IME Switcher button is * requested visible, and the navigation bar is not requested visible. * * <li>The IME should draw the IME navigation bar.</li> * <li>The IME Switcher button should be visible when the IME is visible.</li> * <li>The IME navigation bar should be visible, but was requested hidden by the IME.</li> * @param buttonVisible whether the IME Switcher button is requested visible. * @param shouldDrawImeNavBar whether the IME navigation bar should be drawn. * @param imeNavBarNotVisible whether the IME navigation bar is not requested visible. This * will be {@code true} if it is requested hidden or not * installed. */ private void checkCustomImeSwitcherVisibility() { private void checkCustomImeSwitcherButtonRequestedVisible(boolean buttonVisible, boolean shouldDrawImeNavBar, boolean imeNavBarNotVisible) { if (!Flags.imeSwitcherRevampApi()) { return; } final boolean visible = mImeDrawsImeNavBar && mShouldShowImeSwitcherWhenImeIsShown && mNavigationBarFrame != null && !isShown(); if (visible != mCustomImeSwitcherVisible) { mCustomImeSwitcherVisible = visible; mService.onCustomImeSwitcherButtonRequestedVisible(mCustomImeSwitcherVisible); // The system nav bar will be hidden when the IME is shown and the config is set. final boolean navBarNotVisible = shouldDrawImeNavBar ? imeNavBarNotVisible : mService.getResources().getBoolean( com.android.internal.R.bool.config_hideNavBarForKeyboard); final boolean visible = buttonVisible && navBarNotVisible; if (visible != mCustomImeSwitcherButtonRequestedVisible) { mCustomImeSwitcherButtonRequestedVisible = visible; mService.onCustomImeSwitcherButtonRequestedVisible(visible); } } Loading @@ -656,7 +663,8 @@ final class NavigationBarController { + " mNavigationBarFrame=" + mNavigationBarFrame + " mShouldShowImeSwitcherWhenImeIsShown=" + mShouldShowImeSwitcherWhenImeIsShown + " mCustomImeSwitcherVisible=" + mCustomImeSwitcherVisible + " mCustomImeSwitcherButtonRequestedVisible=" + mCustomImeSwitcherButtonRequestedVisible + " mAppearance=0x" + Integer.toHexString(mAppearance) + " mDarkIntensity=" + mDarkIntensity + " mDrawLegacyNavigationBarBackground=" + mDrawLegacyNavigationBarBackground Loading