diff options
| author | Adrian Roos <roosa@google.com> | 2018-04-30 16:05:00 +0200 |
|---|---|---|
| committer | Adrian Roos <roosa@google.com> | 2018-05-02 12:58:54 +0000 |
| commit | 786ea783ea109c67a50871b9a35dfb3c485b9585 (patch) | |
| tree | d097d30020e7bef88d662100f4873bbc0c25baf1 /core/java | |
| parent | a6ef087d245d480f87522db4e5eefd5fb4f8e568 (diff) | |
BackgroundFallback: Cover all cases where the fallback is needed
Fixes an issue where uncovered regions were not
covered if they are to the right or bottom of the
content view.
Fixes: 78661186
Test: Install test app from bug, enable cuotut, open test app, go to landscape, verify white fallback background is drawn in both landscape and seascape
Test: atest BackgroundFallbackTest
Change-Id: I442f03395a71550a534d64233762aa84002319dd
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/internal/policy/DecorView.java | 6 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/BackgroundFallback.java | 82 |
2 files changed, 77 insertions, 11 deletions
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index eadefc919934..cfc5c4cebea9 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -310,10 +310,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind public void onDraw(Canvas c) { super.onDraw(c); - // When we are resizing, we need the fallback background to cover the area where we have our - // system bar background views as the navigation bar will be hidden during resizing. - mBackgroundFallback.draw(isResizing() ? this : mContentRoot, mContentRoot, c, - mWindow.mContentParent); + mBackgroundFallback.draw(this, mContentRoot, c, mWindow.mContentParent, + mStatusColorViewState.view, mNavigationColorViewState.view); } @Override diff --git a/core/java/com/android/internal/widget/BackgroundFallback.java b/core/java/com/android/internal/widget/BackgroundFallback.java index 309f80cb0d52..2b05f1ecbc70 100644 --- a/core/java/com/android/internal/widget/BackgroundFallback.java +++ b/core/java/com/android/internal/widget/BackgroundFallback.java @@ -46,8 +46,11 @@ public class BackgroundFallback { * @param root The view group containing the content. * @param c The canvas to draw the background onto. * @param content The view where the actual app content is contained in. + * @param coveringView1 A potentially opaque view drawn atop the content + * @param coveringView2 A potentially opaque view drawn atop the content */ - public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content) { + public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content, + View coveringView1, View coveringView2) { if (!hasFallback()) { return; } @@ -55,6 +58,10 @@ public class BackgroundFallback { // Draw the fallback in the padding. final int width = boundsView.getWidth(); final int height = boundsView.getHeight(); + + final int rootOffsetX = root.getLeft(); + final int rootOffsetY = root.getTop(); + int left = width; int top = height; int right = 0; @@ -71,17 +78,58 @@ public class BackgroundFallback { ((ViewGroup) child).getChildCount() == 0) { continue; } - } else if (child.getVisibility() != View.VISIBLE || childBg == null || - childBg.getOpacity() != PixelFormat.OPAQUE) { + } else if (child.getVisibility() != View.VISIBLE || !isOpaque(childBg)) { // Potentially translucent or invisible children don't count, and we assume // the content view will cover the whole area if we're in a background // fallback situation. continue; } - left = Math.min(left, child.getLeft()); - top = Math.min(top, child.getTop()); - right = Math.max(right, child.getRight()); - bottom = Math.max(bottom, child.getBottom()); + left = Math.min(left, rootOffsetX + child.getLeft()); + top = Math.min(top, rootOffsetY + child.getTop()); + right = Math.max(right, rootOffsetX + child.getRight()); + bottom = Math.max(bottom, rootOffsetY + child.getBottom()); + } + + // If one of the bar backgrounds is a solid color and covers the entire padding on a side + // we can drop that padding. + boolean eachBarCoversTopInY = true; + for (int i = 0; i < 2; i++) { + View v = (i == 0) ? coveringView1 : coveringView2; + if (v == null || v.getVisibility() != View.VISIBLE + || v.getAlpha() != 1f || !isOpaque(v.getBackground())) { + eachBarCoversTopInY = false; + continue; + } + + // Bar covers entire left padding + if (v.getTop() <= 0 && v.getBottom() >= height + && v.getLeft() <= 0 && v.getRight() >= left) { + left = 0; + } + // Bar covers entire right padding + if (v.getTop() <= 0 && v.getBottom() >= height + && v.getLeft() <= right && v.getRight() >= width) { + right = width; + } + // Bar covers entire top padding + if (v.getTop() <= 0 && v.getBottom() >= top + && v.getLeft() <= 0 && v.getRight() >= width) { + top = 0; + } + // Bar covers entire bottom padding + if (v.getTop() <= bottom && v.getBottom() >= height + && v.getLeft() <= 0 && v.getRight() >= width) { + bottom = height; + } + + eachBarCoversTopInY &= v.getTop() <= 0 && v.getBottom() >= top; + } + + // Special case: Sometimes, both covering views together may cover the top inset, but + // neither does on its own. + if (eachBarCoversTopInY && (viewsCoverEntireWidth(coveringView1, coveringView2, width) + || viewsCoverEntireWidth(coveringView2, coveringView1, width))) { + top = 0; } if (left >= right || top >= bottom) { @@ -106,4 +154,24 @@ public class BackgroundFallback { mBackgroundFallback.draw(c); } } + + private boolean isOpaque(Drawable childBg) { + return childBg != null && childBg.getOpacity() == PixelFormat.OPAQUE; + } + + /** + * Returns true if {@code view1} starts before or on {@code 0} and extends at least + * up to {@code view2}, and that view extends at least to {@code width}. + * + * @param view1 the first view to check if it covers the width + * @param view2 the second view to check if it covers the width + * @param width the width to check for + * @return returns true if both views together cover the entire width (and view1 is to the left + * of view2) + */ + private boolean viewsCoverEntireWidth(View view1, View view2, int width) { + return view1.getLeft() <= 0 + && view1.getRight() >= view2.getLeft() + && view2.getRight() >= width; + } } |
