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
This commit is contained in:
Yohei Yukawa
2022-01-31 18:56:59 -08:00
parent af1695a78a
commit c98b9c8f40
3 changed files with 71 additions and 7 deletions

View File

@@ -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;
}
mNavigationBarFrame.setBackground(null);
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
+ "}";
}
}

View File

@@ -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.
*

View File

@@ -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;