Force app to draw navigation bar background

For gestural navigation, having a small bar drawn by SystemUI
looks really really weird. Since we force the status bar
background to be drawn in the client, we can also force the
navigation bar background without expecting any compat issues.

Bug: 129751541
Test: Open legacy app, ensure black is drawn in the client
Change-Id: I9cd4c5dd799324ff10bf9d28750e8f238ab1e459
(cherry picked from commit 461bb11371e956ab1ab2e19940d393d9d729be54)
(cherry picked from commit a6aabacbb5f7704e177e9c72dd038939a24ffedc)
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bd38327..c2aec6a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1746,7 +1746,7 @@
          * what the other flags are.
          * @hide
          */
-        public static final int PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND = 0x00020000;
+        public static final int PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS = 0x00020000;
 
         /**
          * Flag to indicate that this window needs Sustained Performance Mode if
@@ -1877,8 +1877,8 @@
                         equals = PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
                         name = "LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"),
                 @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND,
-                        equals = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND,
+                        mask = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS,
+                        equals = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS,
                         name = "FORCE_DRAW_STATUS_BAR_BACKGROUND"),
                 @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 625814d..66a6329 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -38,7 +38,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
-
 import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
 
 import android.animation.Animator;
@@ -53,6 +52,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Insets;
 import android.graphics.LinearGradient;
 import android.graphics.Outline;
 import android.graphics.Paint;
@@ -205,8 +205,8 @@
     private final Interpolator mShowInterpolator;
     private final Interpolator mHideInterpolator;
     private final int mBarEnterExitDuration;
-    final boolean mForceWindowDrawsStatusBarBackground;
-    private final int mSemiTransparentStatusBarColor;
+    final boolean mForceWindowDrawsBarBackgrounds;
+    private final int mSemiTransparentBarColor;
 
     private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
 
@@ -242,6 +242,8 @@
     private boolean mWindowResizeCallbacksAdded = false;
     private Drawable.Callback mLastBackgroundDrawableCb = null;
     private BackdropFrameRenderer mBackdropFrameRenderer = null;
+    private Drawable mOriginalBackgroundDrawable;
+    private Drawable mLastOriginalBackgroundDrawable;
     private Drawable mResizingBackgroundDrawable;
     private Drawable mCaptionBackgroundDrawable;
     private Drawable mUserCaptionBackgroundDrawable;
@@ -257,6 +259,8 @@
     private final int mResizeShadowSize;
     private final Paint mVerticalResizeShadowPaint = new Paint();
     private final Paint mHorizontalResizeShadowPaint = new Paint();
+    private Insets mBackgroundInsets = Insets.NONE;
+    private Insets mLastBackgroundInsets = Insets.NONE;
 
     DecorView(Context context, int featureId, PhoneWindow window,
             WindowManager.LayoutParams params) {
@@ -270,10 +274,10 @@
 
         mBarEnterExitDuration = context.getResources().getInteger(
                 R.integer.dock_enter_exit_duration);
-        mForceWindowDrawsStatusBarBackground = context.getResources().getBoolean(
+        mForceWindowDrawsBarBackgrounds = context.getResources().getBoolean(
                 R.bool.config_forceWindowDrawsStatusBarBackground)
                 && context.getApplicationInfo().targetSdkVersion >= N;
-        mSemiTransparentStatusBarColor = context.getResources().getColor(
+        mSemiTransparentBarColor = context.getResources().getColor(
                 R.color.system_bar_background_semi_transparent, null /* theme */);
 
         updateAvailableWidth();
@@ -948,8 +952,9 @@
     }
 
     public void setWindowBackground(Drawable drawable) {
-        if (getBackground() != drawable) {
-            setBackgroundDrawable(drawable);
+        if (mOriginalBackgroundDrawable != drawable) {
+            mOriginalBackgroundDrawable = drawable;
+            updateBackgroundDrawable();
             if (drawable != null) {
                 mResizingBackgroundDrawable = enforceNonTranslucentBackground(drawable,
                         mWindow.isTranslucent() || mWindow.isShowingWallpaper());
@@ -1114,9 +1119,10 @@
             boolean navBarToLeftEdge = isNavBarToLeftEdge(mLastBottomInset, mLastLeftInset);
             int navBarSize = getNavBarSize(mLastBottomInset, mLastRightInset, mLastLeftInset);
             updateColorViewInt(mNavigationColorViewState, sysUiVisibility,
-                    mWindow.mNavigationBarColor, mWindow.mNavigationBarDividerColor, navBarSize,
+                    calculateNavigationBarColor(), mWindow.mNavigationBarDividerColor, navBarSize,
                     navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
-                    0 /* sideInset */, animate && !disallowAnimate, false /* force */);
+                    0 /* sideInset */, animate && !disallowAnimate,
+                    mForceWindowDrawsBarBackgrounds);
 
             boolean statusBarNeedsRightInset = navBarToRightEdge
                     && mNavigationColorViewState.present;
@@ -1128,24 +1134,34 @@
                     calculateStatusBarColor(), 0, mLastTopInset,
                     false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
                     animate && !disallowAnimate,
-                    mForceWindowDrawsStatusBarBackground);
+                    mForceWindowDrawsBarBackgrounds);
         }
 
-        // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
-        // to ensure that the rest of the view hierarchy doesn't notice it, unless they've
-        // explicitly asked for it.
-        boolean consumingNavBar =
-                (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
+        // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS or
+        // mForceWindowDrawsBarBackgrounds, we still need to ensure that the rest of the view
+        // hierarchy doesn't notice it, unless they've explicitly asked for it.
+        //
+        // Note: We don't need to check for IN_SCREEN or INSET_DECOR because unlike the status bar,
+        // these flags wouldn't make the window draw behind the navigation bar, unless
+        // LAYOUT_HIDE_NAVIGATION was set.
+        boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
+                        && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
-                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
+                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
                 || mLastShouldAlwaysConsumeSystemBars;
 
+        boolean consumingNavBar =
+                ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
+                        && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
+                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
+                || forceConsumingNavBar;
+
         // If we didn't request fullscreen layout, but we still got it because of the
-        // mForceWindowDrawsStatusBarBackground flag, also consume top inset.
+        // mForceWindowDrawsBarBackgrounds flag, also consume top inset.
         boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
                 && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
                 && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
-                && mForceWindowDrawsStatusBarBackground
+                && mForceWindowDrawsBarBackgrounds
                 && mLastTopInset != 0
                 || mLastShouldAlwaysConsumeSystemBars;
 
@@ -1176,21 +1192,63 @@
             }
         }
 
+        if (forceConsumingNavBar) {
+            mBackgroundInsets = Insets.of(mLastLeftInset, 0, mLastRightInset, mLastBottomInset);
+        } else {
+            mBackgroundInsets = Insets.NONE;
+        }
+        updateBackgroundDrawable();
+
         if (insets != null) {
             insets = insets.consumeStableInsets();
         }
         return insets;
     }
 
-    private int calculateStatusBarColor() {
-        return calculateStatusBarColor(mWindow.getAttributes().flags,
-                mSemiTransparentStatusBarColor, mWindow.mStatusBarColor);
+    /**
+     * Updates the background drawable, applying padding to it in case we {@link #mBackgroundInsets}
+     * are set.
+     */
+    private void updateBackgroundDrawable() {
+        if (mBackgroundInsets.equals(mLastBackgroundInsets)
+                && mLastOriginalBackgroundDrawable == mOriginalBackgroundDrawable) {
+            return;
+        }
+        if (mBackgroundInsets.equals(Insets.NONE)) {
+            setBackground(mOriginalBackgroundDrawable);
+        } else {
+            setBackground(new InsetDrawable(mOriginalBackgroundDrawable,
+                    mBackgroundInsets.left, mBackgroundInsets.top,
+                    mBackgroundInsets.right, mBackgroundInsets.bottom) {
+
+                /**
+                 * Return inner padding so we don't apply the padding again in
+                 * {@link DecorView#drawableChanged()}
+                 */
+                @Override
+                public boolean getPadding(Rect padding) {
+                    return getDrawable().getPadding(padding);
+                }
+            });
+        }
+        mLastBackgroundInsets = mBackgroundInsets;
+        mLastOriginalBackgroundDrawable = mOriginalBackgroundDrawable;
     }
 
-    public static int calculateStatusBarColor(int flags, int semiTransparentStatusBarColor,
-            int statusBarColor) {
-        return (flags & FLAG_TRANSLUCENT_STATUS) != 0 ? semiTransparentStatusBarColor
-                : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? statusBarColor
+    private int calculateStatusBarColor() {
+        return calculateBarColor(mWindow.getAttributes().flags, FLAG_TRANSLUCENT_STATUS,
+                mSemiTransparentBarColor, mWindow.mStatusBarColor);
+    }
+
+    private int calculateNavigationBarColor() {
+        return calculateBarColor(mWindow.getAttributes().flags, FLAG_TRANSLUCENT_NAVIGATION,
+                mSemiTransparentBarColor, mWindow.mNavigationBarColor);
+    }
+
+    public static int calculateBarColor(int flags, int translucentFlag, int semiTransparentBarColor,
+            int barColor) {
+        return (flags & translucentFlag) != 0 ? semiTransparentBarColor
+                : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? barColor
                 : Color.BLACK;
     }
 
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 890ee86..04559e4 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -31,7 +31,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 
 import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
@@ -2469,8 +2469,8 @@
                 setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
                         FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
             }
-            if (mDecor.mForceWindowDrawsStatusBarBackground) {
-                params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+            if (mDecor.mForceWindowDrawsBarBackgrounds) {
+                params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
             }
         }
         if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ec2a6ae..21f5acb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1302,12 +1302,6 @@
     <!-- Disable lockscreen rotation by default -->
     <bool name="config_enableLockScreenRotation">false</bool>
 
-    <!-- Enable lockscreen translucent decor by default -->
-    <bool name="config_enableLockScreenTranslucentDecor">true</bool>
-
-    <!-- Enable translucent decor by default -->
-    <bool name="config_enableTranslucentDecor">true</bool>
-
     <!-- Is the device capable of hot swapping an UICC Card -->
     <bool name="config_hotswapCapable">false</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3e23640..fb7be77 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1717,8 +1717,6 @@
   <java-symbol type="bool" name="config_enableCarDockHomeLaunch" />
   <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
   <java-symbol type="bool" name="config_enableLockScreenRotation" />
-  <java-symbol type="bool" name="config_enableLockScreenTranslucentDecor" />
-  <java-symbol type="bool" name="config_enableTranslucentDecor" />
   <java-symbol type="bool" name="config_forceShowSystemBars" />
   <java-symbol type="bool" name="config_lidControlsScreenLock" />
   <java-symbol type="bool" name="config_lidControlsSleep" />
diff --git a/packages/SystemUI/res-keyguard/values/alias.xml b/packages/SystemUI/res-keyguard/values/alias.xml
index 1c63c79..6d49b1f 100644
--- a/packages/SystemUI/res-keyguard/values/alias.xml
+++ b/packages/SystemUI/res-keyguard/values/alias.xml
@@ -28,9 +28,6 @@
     <!-- Alias used to reference framework configuration for screen rotation.  -->
     <item type="bool" name="config_enableLockScreenRotation">@*android:bool/config_enableLockScreenRotation</item>
 
-    <!-- Alias used to reference framework configuration for translucent decor.  -->
-    <item type="bool" name="config_enableLockScreenTranslucentDecor">@*android:bool/config_enableLockScreenTranslucentDecor</item>
-
     <!-- Alias used to reference framework activity duration.  -->
     <item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
 
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index bbb857f..6ae7720 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -49,7 +49,7 @@
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
@@ -211,7 +211,6 @@
 
     private final boolean mCarDockEnablesAccelerometer;
     private final boolean mDeskDockEnablesAccelerometer;
-    private final boolean mTranslucentDecorEnabled;
     private final AccessibilityManager mAccessibilityManager;
     private final ImmersiveModeConfirmation mImmersiveModeConfirmation;
     private final ScreenshotHelper mScreenshotHelper;
@@ -434,7 +433,6 @@
         final Resources r = mContext.getResources();
         mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
         mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
-        mTranslucentDecorEnabled = r.getBoolean(R.bool.config_enableTranslucentDecor);
         mForceShowSystemBarsFromExternal = r.getBoolean(R.bool.config_forceShowSystemBars);
 
         mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
@@ -1287,14 +1285,12 @@
 
     private static int getImpliedSysUiFlagsForLayout(LayoutParams attrs) {
         int impliedFlags = 0;
-        if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
-            impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
-        }
-        final boolean forceWindowDrawsStatusBarBackground =
-                (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+        final boolean forceWindowDrawsBarBackgrounds =
+                (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0
+                && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT;
         if ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
-                || forceWindowDrawsStatusBarBackground
-                && attrs.height == MATCH_PARENT && attrs.width == MATCH_PARENT) {
+                || forceWindowDrawsBarBackgrounds) {
+            impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
             impliedFlags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
         }
         return impliedFlags;
@@ -1396,9 +1392,6 @@
         navTranslucent &= !immersiveSticky;  // transient trumps translucent
         boolean isKeyguardShowing = isStatusBarKeyguard()
                 && !mService.mPolicy.isKeyguardOccluded();
-        if (!isKeyguardShowing) {
-            navTranslucent &= areTranslucentBarsAllowed();
-        }
         boolean statusBarForcesShowingNavigation = !isKeyguardShowing && mStatusBar != null
                 && (mStatusBar.getAttrs().privateFlags
                 & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
@@ -1560,9 +1553,6 @@
         boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
         boolean statusBarTranslucent = (sysui
                 & (View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT)) != 0;
-        if (!isKeyguardShowing) {
-            statusBarTranslucent &= areTranslucentBarsAllowed();
-        }
 
         // If the status bar is hidden, we don't want to cause windows behind it to scroll.
         if (mStatusBar.isVisibleLw() && !statusBarTransient) {
@@ -1915,13 +1905,14 @@
                         && (fl & FLAG_FULLSCREEN) == 0
                         && (fl & FLAG_TRANSLUCENT_STATUS) == 0
                         && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
-                        && (pfl & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) == 0) {
+                        && (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) {
                     // Ensure policy decor includes status bar
                     dcf.top = displayFrames.mStable.top;
                 }
                 if ((fl & FLAG_TRANSLUCENT_NAVIGATION) == 0
                         && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
-                        && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
+                        && (fl & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
+                        && (pfl & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) == 0) {
                     // Ensure policy decor includes navigation bar
                     dcf.bottom = displayFrames.mStable.bottom;
                     dcf.right = displayFrames.mStable.right;
@@ -3148,6 +3139,8 @@
                 drawsStatusBarBackground(vis, mTopFullscreenOpaqueWindowState);
         final boolean dockedDrawsStatusBarBackground =
                 drawsStatusBarBackground(dockedVis, mTopDockedOpaqueWindowState);
+        final boolean fullscreenDrawsNavBarBackground =
+                drawsNavigationBarBackground(vis, mTopFullscreenOpaqueWindowState);
 
         // prevent status bar interaction from clearing certain flags
         int type = win.getAttrs().type;
@@ -3167,12 +3160,12 @@
         if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) {
             vis |= View.STATUS_BAR_TRANSPARENT;
             vis &= ~View.STATUS_BAR_TRANSLUCENT;
-        } else if ((!areTranslucentBarsAllowed() && fullscreenTransWin != mStatusBar)
-                || forceOpaqueStatusBar) {
+        } else if (forceOpaqueStatusBar) {
             vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT);
         }
 
-        vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing);
+        vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing,
+                fullscreenDrawsNavBarBackground);
 
         // update status bar
         boolean immersiveSticky =
@@ -3256,8 +3249,9 @@
         return vis;
     }
 
-    private boolean drawsStatusBarBackground(int vis, WindowState win) {
-        if (!mStatusBarController.isTransparentAllowed(win)) {
+    private boolean drawsBarBackground(int vis, WindowState win, BarController controller,
+            int translucentFlag) {
+        if (!controller.isTransparentAllowed(win)) {
             return false;
         }
         if (win == null) {
@@ -3267,9 +3261,17 @@
         final boolean drawsSystemBars =
                 (win.getAttrs().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
         final boolean forceDrawsSystemBars =
-                (win.getAttrs().privateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+                (win.getAttrs().privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
 
-        return forceDrawsSystemBars || drawsSystemBars && (vis & View.STATUS_BAR_TRANSLUCENT) == 0;
+        return forceDrawsSystemBars || drawsSystemBars && (vis & translucentFlag) == 0;
+    }
+
+    private boolean drawsStatusBarBackground(int vis, WindowState win) {
+        return drawsBarBackground(vis, win, mStatusBarController, FLAG_TRANSLUCENT_STATUS);
+    }
+
+    private boolean drawsNavigationBarBackground(int vis, WindowState win) {
+        return drawsBarBackground(vis, win, mNavigationBarController, FLAG_TRANSLUCENT_NAVIGATION);
     }
 
     /**
@@ -3277,10 +3279,13 @@
      *         on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
      */
     private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
-            boolean freeformStackVisible, boolean isDockedDividerResizing) {
+            boolean freeformStackVisible, boolean isDockedDividerResizing,
+            boolean fullscreenDrawsBackground) {
         if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
             if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
                 visibility = setNavBarOpaqueFlag(visibility);
+            } else if (fullscreenDrawsBackground) {
+                visibility = setNavBarTransparentFlag(visibility);
             }
         } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
             if (isDockedDividerResizing) {
@@ -3292,9 +3297,6 @@
             }
         }
 
-        if (!areTranslucentBarsAllowed()) {
-            visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT;
-        }
         return visibility;
     }
 
@@ -3307,6 +3309,11 @@
         return visibility | View.NAVIGATION_BAR_TRANSLUCENT;
     }
 
+    private int setNavBarTransparentFlag(int visibility) {
+        visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT;
+        return visibility | View.NAVIGATION_BAR_TRANSPARENT;
+    }
+
     private void clearClearableFlagsLw() {
         int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
         if (newVal != mResettingSystemUiFlags) {
@@ -3338,16 +3345,6 @@
         return (systemUiFlags & disableNavigationBar) == disableNavigationBar;
     }
 
-    /**
-     * @return whether the navigation or status bar can be made translucent
-     *
-     * This should return true unless touch exploration is not enabled or
-     * R.boolean.config_enableTranslucentDecor is false.
-     */
-    private boolean areTranslucentBarsAllowed() {
-        return mTranslucentDecorEnabled;
-    }
-
     boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
             int newRotation) {
         // For the upside down rotation we don't rotate seamlessly as the navigation
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index dafed9e..39b5662 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -29,8 +29,10 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
 import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 
 import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
@@ -104,7 +106,7 @@
             | FLAG_SCALED
             | FLAG_SECURE;
 
-    private static final int PRIVATE_FLAG_INHERITS = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+    private static final int PRIVATE_FLAG_INHERITS = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM;
     private static final int MSG_REPORT_DRAW = 0;
@@ -493,10 +495,12 @@
             mWindowPrivateFlags = windowPrivateFlags;
             mSysUiVis = sysUiVis;
             final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
-            mStatusBarColor = DecorView.calculateStatusBarColor(windowFlags,
-                    context.getColor(R.color.system_bar_background_semi_transparent),
-                    statusBarColor);
-            mNavigationBarColor = navigationBarColor;
+            final int semiTransparent = context.getColor(
+                    R.color.system_bar_background_semi_transparent);
+            mStatusBarColor = DecorView.calculateBarColor(windowFlags, FLAG_TRANSLUCENT_STATUS,
+                    semiTransparent, statusBarColor);
+            mNavigationBarColor = DecorView.calculateBarColor(windowFlags,
+                    FLAG_TRANSLUCENT_NAVIGATION, semiTransparent, navigationBarColor);
             mStatusBarPaint.setColor(mStatusBarColor);
             mNavigationBarPaint.setColor(navigationBarColor);
         }
@@ -507,10 +511,10 @@
         }
 
         int getStatusBarColorViewHeight() {
-            final boolean forceStatusBarBackground =
-                    (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+            final boolean forceBarBackground =
+                    (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
             if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
-                    mSysUiVis, mStatusBarColor, mWindowFlags, forceStatusBarBackground)) {
+                    mSysUiVis, mStatusBarColor, mWindowFlags, forceBarBackground)) {
                 return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
             } else {
                 return 0;
@@ -518,8 +522,10 @@
         }
 
         private boolean isNavigationBarColorViewVisible() {
+            final boolean forceBarBackground =
+                    (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
             return NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
-                    mSysUiVis, mNavigationBarColor, mWindowFlags, false /* force */);
+                    mSysUiVis, mNavigationBarColor, mWindowFlags, forceBarBackground);
         }
 
         void drawDecors(Canvas c, @Nullable Rect alreadyDrawnFrame) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 03969da..e90f094 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -27,7 +27,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -142,20 +142,20 @@
     }
 
     @Test
-    public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
+    public void layoutWindowLw_appWontDrawBars_forceStatusAndNav() throws Exception {
         synchronized (mWm.mGlobalLock) {
             mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-            mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+            mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
             addWindow(mWindow);
 
             mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
             mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
             assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
             assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
-            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
         }
     }