summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-05-03 13:55:38 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-05-03 13:55:38 +0000
commit0d58b9bb647e49688d01661f51398df19701fcec (patch)
tree6e641ac0cf53d7df01e20e393342b78c7e63918d /core/java
parentaeaefe91bcd3c7465b638a33378e6b3b7c00fd56 (diff)
parent786ea783ea109c67a50871b9a35dfb3c485b9585 (diff)
Merge "BackgroundFallback: Cover all cases where the fallback is needed" into pi-dev
Diffstat (limited to 'core/java')
-rw-r--r--core/java/com/android/internal/policy/DecorView.java6
-rw-r--r--core/java/com/android/internal/widget/BackgroundFallback.java82
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 cc95df7724ba..2db573918e8a 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -308,10 +308,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;
+ }
}