DecorView#mNavigationGuard is gone
With this CL, DecorView#mNavigationGuard that handles navigation bar
only for IME windows [1] is finally gone and replaced with the
standard mechanism to handle navigation bar layout padding /
background color.
This CL addresses multiple anomalies regarding how the following APIs
work for IME windows.
* Window#setNavigationBarColor()
* Previous behavior:
- Only works for Color#TRANSPARENT [2].
- Ignores FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS.
* New behavior:
- Works as documented.
- Requires FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS to work.
* SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION flag
* Previous behavior:
- The system automatically sets
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION to the IME windows [3].
- Does not work as documented. Content area is not extended to the
navigation bar area.
- Manually unsetting SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION can cause
unexpected layout, because the system expects that this flag is
always set to the IME window.
- Had a special logic for FLAG_LAYOUT_IN_OVERSCAN [4].
* New behavior:
- Works as documented.
- Can set/unset as necessary.
From the viewpoint of IME developers, this CL enables IME windows to
* correctly extend the input view to the navigation bar region by
using SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION as documented, instead of
relying on a special hack with FLAG_LAYOUT_IN_OVERSCAN hack.
* use Window#setNavigationBarColor() to easily change the navigation
bar background color, like other non-floating windows.
Note that SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR is not yet supported for
IME windows, which will be implemented in a subsequent CL.
[1]: I6a93f30aec83f1cecfb854073046cbc87ab4aa66
ae3349e1c34f7aceddc526cd11d9ac44951e97b6
[2]: Iea77915ecc55eedaf19899e72c44f704ba9d852c
0a9d1ea015af24056018ec02f6d9afd2f62243ba
[3]: I460912ee7c117480c57b947ed31eca330819f32c
c68d577f29604d205573ee4253704c5b2c5e4f81
[4]: Ic38f204a892bf34e8dae65990d5aa8c95af555d8
9b32a35aa7d47d39da919e777e2fe271cc83fa1c
[5]: I4b10a19641bd3ce6c43e7629404b6f202d4186e8
Fix: 25706186
Bug: 69002467
Test: ThemedNavBarKeyboard sample [5] works for the following cases
* Extended Dark Navigation Bar
* Separate Dark Navigation Bar
* Floating Mode (if the target app uses dark navigation bar)
Change-Id: I664630099b6eb3fe31675444ba94944cb0eb98b0
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 02b1c65..8937490 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -18,6 +18,7 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import android.annotation.CallSuper;
import android.annotation.DrawableRes;
@@ -852,6 +853,11 @@
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(this, "InputMethod", mTheme, null, null, mDispatcherState,
WindowManager.LayoutParams.TYPE_INPUT_METHOD, Gravity.BOTTOM, false);
+ // For ColorView in DecorView to work, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS needs to be set
+ // by default (but IME developers can opt this out later if they want a new behavior).
+ mWindow.getWindow().setFlags(
+ FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+
initViews();
mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
}
@@ -882,8 +888,6 @@
mThemeAttrs = obtainStyledAttributes(android.R.styleable.InputMethodService);
mRootView = mInflater.inflate(
com.android.internal.R.layout.input_method, null);
- mRootView.setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mWindow.setContentView(mRootView);
mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsComputer);
mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 5fddfba..95bc352 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -101,7 +101,6 @@
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
@@ -194,8 +193,6 @@
// View added at runtime to draw under the status bar area
private View mStatusGuard;
- // View added at runtime to draw under the navigation bar area
- private View mNavigationGuard;
private final ColorViewState mStatusColorViewState =
new ColorViewState(STATUS_BAR_COLOR_VIEW_ATTRIBUTES);
@@ -1002,7 +999,6 @@
mFrameOffsets.set(insets.getSystemWindowInsets());
insets = updateColorViews(insets, true /* animate */);
insets = updateStatusGuard(insets);
- insets = updateNavigationGuard(insets);
if (getForeground() != null) {
drawableChanged();
}
@@ -1062,7 +1058,10 @@
WindowManager.LayoutParams attrs = mWindow.getAttributes();
int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
- if (!mWindow.mIsFloating) {
+ // IME is an exceptional floating window that requires color view.
+ final boolean isImeWindow =
+ mWindow.getAttributes().type == WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+ if (!mWindow.mIsFloating || isImeWindow) {
boolean disallowAnimate = !isLaidOut();
disallowAnimate |= ((mLastWindowFlags ^ attrs.flags)
& FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
@@ -1363,7 +1362,7 @@
if (mStatusGuard == null) {
mStatusGuard = new View(mContext);
mStatusGuard.setBackgroundColor(mContext.getColor(
- R.color.input_method_navigation_guard));
+ R.color.decor_view_status_guard));
addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
new LayoutParams(LayoutParams.MATCH_PARENT,
mlp.topMargin, Gravity.START | Gravity.TOP));
@@ -1407,51 +1406,6 @@
return insets;
}
- private WindowInsets updateNavigationGuard(WindowInsets insets) {
- // IME windows lay out below the nav bar, but the content view must not (for back compat)
- // Only make this adjustment if the window is not requesting layout in overscan
- if (mWindow.getAttributes().type == WindowManager.LayoutParams.TYPE_INPUT_METHOD
- && (mWindow.getAttributes().flags & FLAG_LAYOUT_IN_OVERSCAN) == 0) {
- // prevent the content view from including the nav bar height
- if (mWindow.mContentParent != null) {
- if (mWindow.mContentParent.getLayoutParams() instanceof MarginLayoutParams) {
- MarginLayoutParams mlp =
- (MarginLayoutParams) mWindow.mContentParent.getLayoutParams();
- mlp.bottomMargin = insets.getSystemWindowInsetBottom();
- mWindow.mContentParent.setLayoutParams(mlp);
- }
- }
- // position the navigation guard view, creating it if necessary
- if (mNavigationGuard == null) {
- mNavigationGuard = new View(mContext);
- mNavigationGuard.setBackgroundColor(mContext.getColor(
- R.color.input_method_navigation_guard));
- addView(mNavigationGuard, indexOfChild(mNavigationColorViewState.view),
- new LayoutParams(LayoutParams.MATCH_PARENT,
- insets.getSystemWindowInsetBottom(),
- Gravity.START | Gravity.BOTTOM));
- } else {
- LayoutParams lp = (LayoutParams) mNavigationGuard.getLayoutParams();
- lp.height = insets.getSystemWindowInsetBottom();
- mNavigationGuard.setLayoutParams(lp);
- }
- updateNavigationGuardColor();
- insets = insets.consumeSystemWindowInsets(
- false, false, false, true /* bottom */);
- }
- return insets;
- }
-
- void updateNavigationGuardColor() {
- if (mNavigationGuard != null) {
- // Make navigation bar guard invisible if the transparent color is specified.
- // Only TRANSPARENT is sufficient for hiding the navigation bar if the no software
- // keyboard is shown by IMS.
- mNavigationGuard.setVisibility(mWindow.getNavigationBarColor() == Color.TRANSPARENT ?
- View.INVISIBLE : View.VISIBLE);
- }
- }
-
/**
* Overrides the view outline when the activity enters picture-in-picture to ensure that it has
* an opaque shadow even if the window background is completely transparent. This only applies
@@ -2103,7 +2057,7 @@
for (int i = getChildCount() - 1; i >= 0; i--) {
View v = getChildAt(i);
if (v != mStatusColorViewState.view && v != mNavigationColorViewState.view
- && v != mStatusGuard && v != mNavigationGuard) {
+ && v != mStatusGuard) {
removeViewAt(i);
}
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index b13560c..e8ee29d 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3807,7 +3807,6 @@
mForcedNavigationBarColor = true;
if (mDecor != null) {
mDecor.updateColorViews(null, false /* animate */);
- mDecor.updateNavigationGuardColor();
}
}
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index fd78500..a078d8b 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -73,7 +73,7 @@
<drawable name="editbox_dropdown_light_frame">@drawable/editbox_dropdown_background</drawable>
<drawable name="input_method_fullscreen_background">#fff9f9f9</drawable>
- <color name="input_method_navigation_guard">#ff000000</color>
+ <color name="decor_view_status_guard">#ff000000</color>
<!-- For date picker widget -->
<drawable name="selected_day_background">#ff0092f4</drawable>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4343ba0..7eb1597 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1812,7 +1812,7 @@
<java-symbol type="bool" name="config_wimaxEnabled" />
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
- <java-symbol type="color" name="input_method_navigation_guard" />
+ <java-symbol type="color" name="decor_view_status_guard" />
<java-symbol type="drawable" name="ic_notification_ime_default" />
<java-symbol type="drawable" name="ic_menu_refresh" />
<java-symbol type="drawable" name="ic_settings" />