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

Commit c98b9c8f authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Support floating IMEs even when IMEs render the nav buttons

As discussed in Bug 201375975, the nevigation bar handling for
floating IMEs is a bit tricky.

This CL tweaks DecorView behabior only when

  InputMethodService#canImeRenderGesturalNavButtons(),

is true and the IME is floating in the gestural navigation mode.

Fix: 215550296
Test: Manually tested with ThemedNavBarKeyboard sample
  1. Build aosp_coral-userdebug and flash it
  2. adb root
  3. adb shell setprop \
      persist.sys.ime.can_render_gestural_nav_buttons true
  4. adb reboot
  5. make -j ThemedNavBarKeyboard
  6. adb install -r \
      $OUT/system/app/ThemedNavBarKeyboard/ThemedNavBarKeyboard.apk
  7. adb shell ime enable \
      com.example.android.themednavbarkeyboard/.ThemedNavBarKeyboard
  8. adb shell ime set \
      com.example.android.themednavbarkeyboard/.ThemedNavBarKeyboard
  9. Open the Dialer app
 10. Focus in the top edit field.
 11. Tap "FLOATING MODE" mode
 12. Make sure that the navigation buttons are visible.
Change-Id: Ia54499a3c2ac6e33e72f625eba3477fd81649d32
parent af1695a7
Loading
Loading
Loading
Loading
+37 −5
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Region;
@@ -158,6 +159,8 @@ final class NavigationBarController {
        @Nullable
        private ValueAnimator mTintAnimator;

        private boolean mDrawLegacyNavigationBarBackground;

        Impl(@NonNull InputMethodService inputMethodService) {
            mService = inputMethodService;
        }
@@ -226,9 +229,14 @@ final class NavigationBarController {
                mLastInsets = systemInsets;
            }

            if (mDrawLegacyNavigationBarBackground) {
                mNavigationBarFrame.setBackgroundColor(Color.BLACK);
            } else {
                mNavigationBarFrame.setBackground(null);
            }

            setIconTintInternal(calculateTargetDarkIntensity(mAppearance));
            setIconTintInternal(calculateTargetDarkIntensity(mAppearance,
                    mDrawLegacyNavigationBarBackground));
        }

        private void uninstallNavigationBarFrameIfNecessary() {
@@ -478,7 +486,8 @@ final class NavigationBarController {
                return;
            }

            final float targetDarkIntensity = calculateTargetDarkIntensity(mAppearance);
            final float targetDarkIntensity = calculateTargetDarkIntensity(mAppearance,
                    mDrawLegacyNavigationBarBackground);

            if (mTintAnimator != null) {
                mTintAnimator.cancel();
@@ -506,11 +515,33 @@ final class NavigationBarController {
        }

        @FloatRange(from = 0.0f, to = 1.0f)
        private static float calculateTargetDarkIntensity(@Appearance int appearance) {
            final boolean lightNavBar = (appearance & APPEARANCE_LIGHT_NAVIGATION_BARS) != 0;
        private static float calculateTargetDarkIntensity(@Appearance int appearance,
                boolean drawLegacyNavigationBarBackground) {
            final boolean lightNavBar = !drawLegacyNavigationBarBackground
                    && (appearance & APPEARANCE_LIGHT_NAVIGATION_BARS) != 0;
            return lightNavBar ? 1.0f : 0.0f;
        }

        @Override
        public boolean onDrawLegacyNavigationBarBackgroundChanged(
                boolean drawLegacyNavigationBarBackground) {
            if (mDestroyed) {
                return false;
            }

            if (drawLegacyNavigationBarBackground != mDrawLegacyNavigationBarBackground) {
                mDrawLegacyNavigationBarBackground = drawLegacyNavigationBarBackground;
                if (mDrawLegacyNavigationBarBackground) {
                    mNavigationBarFrame.setBackgroundColor(Color.BLACK);
                } else {
                    mNavigationBarFrame.setBackground(null);
                }
                scheduleRelayout();
                onSystemBarAppearanceChanged(mAppearance);
            }
            return drawLegacyNavigationBarBackground;
        }

        @Override
        public String toDebugString() {
            return "{mRenderGesturalNavButtons=" + mRenderGesturalNavButtons
@@ -518,6 +549,7 @@ final class NavigationBarController {
                    + " mShouldShowImeSwitcherWhenImeIsShown" + mShouldShowImeSwitcherWhenImeIsShown
                    + " mAppearance=0x" + Integer.toHexString(mAppearance)
                    + " mDarkIntensity=" + mDarkIntensity
                    + " mDrawLegacyNavigationBarBackground=" + mDrawLegacyNavigationBarBackground
                    + "}";
        }
    }
+28 −0
Original line number Diff line number Diff line
@@ -673,6 +673,24 @@ public abstract class Window {
         * @param appearance The newly applied appearance.
         */
        void onSystemBarAppearanceChanged(@WindowInsetsController.Appearance int appearance);

        /**
         * Called from
         * {@link com.android.internal.policy.DecorView#updateColorViews(WindowInsets, boolean)}
         * when {@link com.android.internal.policy.DecorView#mDrawLegacyNavigationBarBackground} is
         * being updated.
         *
         * @param drawLegacyNavigationBarBackground the new value that is being set to
         *        {@link com.android.internal.policy.DecorView#mDrawLegacyNavigationBarBackground}.
         * @return The value to be set to
         *   {@link com.android.internal.policy.DecorView#mDrawLegacyNavigationBarBackgroundHandled}
         *         on behalf of the {@link com.android.internal.policy.DecorView}.
         *         {@code true} to tell that the Window can render the legacy navigation bar
         *         background on behalf of the {@link com.android.internal.policy.DecorView}.
         *         {@code false} to let {@link com.android.internal.policy.DecorView} handle it.
         */
        boolean onDrawLegacyNavigationBarBackgroundChanged(
                boolean drawLegacyNavigationBarBackground);
    }

    /**
@@ -1019,6 +1037,16 @@ public abstract class Window {
        }
    }

    /** @hide */
    public final boolean onDrawLegacyNavigationBarBackgroundChanged(
            boolean drawLegacyNavigationBarBackground) {
        if (mDecorCallback == null) {
            return false;
        }
        return mDecorCallback.onDrawLegacyNavigationBarBackgroundChanged(
                drawLegacyNavigationBarBackground);
    }

    /**
     * Set a callback for changes of area where caption will draw its content.
     *
+6 −2
Original line number Diff line number Diff line
@@ -285,6 +285,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    private Insets mBackgroundInsets = Insets.NONE;
    private Insets mLastBackgroundInsets = Insets.NONE;
    private boolean mDrawLegacyNavigationBarBackground;
    private boolean mDrawLegacyNavigationBarBackgroundHandled;

    private PendingInsetsController mPendingInsetsController = new PendingInsetsController();

@@ -1171,6 +1172,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            mDrawLegacyNavigationBarBackground = mNavigationColorViewState.visible
                    && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
            if (oldDrawLegacy != mDrawLegacyNavigationBarBackground) {
                mDrawLegacyNavigationBarBackgroundHandled =
                        mWindow.onDrawLegacyNavigationBarBackgroundChanged(
                                mDrawLegacyNavigationBarBackground);
                if (viewRoot != null) {
                    viewRoot.requestInvalidateRootRenderNode();
                }
@@ -1263,7 +1267,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            }
        }

        if (forceConsumingNavBar) {
        if (forceConsumingNavBar && !mDrawLegacyNavigationBarBackgroundHandled) {
            mBackgroundInsets = Insets.of(mLastLeftInset, 0, mLastRightInset, mLastBottomInset);
        } else {
            mBackgroundInsets = Insets.NONE;
@@ -2488,7 +2492,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    }

    private void drawLegacyNavigationBarBackground(RecordingCanvas canvas) {
        if (!mDrawLegacyNavigationBarBackground) {
        if (!mDrawLegacyNavigationBarBackground || mDrawLegacyNavigationBarBackgroundHandled) {
            return;
        }
        View v = mNavigationColorViewState.view;