Merge "Display Cutout: Fix ActionBarOverlayLayout to properly dispatch cutout" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-05-18 22:12:30 +00:00
committed by Android (Google) Code Review
7 changed files with 398 additions and 50 deletions

View File

@@ -9838,26 +9838,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* @hide Compute the insets that should be consumed by this view and the ones
* that should propagate to those under it.
*
* Note: This is used by appcompat's ActionBarOverlayLayout through reflection.
*
* @param inoutInsets the insets given to this view
* @param outLocalInsets the insets that should be applied to this view
* @deprecated use {@link #computeSystemWindowInsets}
* @return
*/
@Deprecated
protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
|| mAttachInfo == null
|| ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
&& !mAttachInfo.mOverscanRequested)) {
outLocalInsets.set(inoutInsets);
inoutInsets.set(0, 0, 0, 0);
return true;
} else {
// The application wants to take care of fitting system window for
// the content... however we still need to take care of any overscan here.
final Rect overscan = mAttachInfo.mOverscanInsets;
outLocalInsets.set(overscan);
inoutInsets.left -= overscan.left;
inoutInsets.top -= overscan.top;
inoutInsets.right -= overscan.right;
inoutInsets.bottom -= overscan.bottom;
return false;
}
WindowInsets innerInsets = computeSystemWindowInsets(new WindowInsets(inoutInsets),
outLocalInsets);
inoutInsets.set(innerInsets.getSystemWindowInsets());
return innerInsets.isSystemWindowInsetsConsumed();
}
/**
@@ -9873,12 +9867,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
|| mAttachInfo == null
|| (mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0) {
|| ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
&& !mAttachInfo.mOverscanRequested)) {
outLocalInsets.set(in.getSystemWindowInsets());
return in.consumeSystemWindowInsets();
return in.consumeSystemWindowInsets().inset(outLocalInsets);
} else {
outLocalInsets.set(0, 0, 0, 0);
return in;
// The application wants to take care of fitting system window for
// the content... however we still need to take care of any overscan here.
final Rect overscan = mAttachInfo.mOverscanInsets;
outLocalInsets.set(overscan);
return in.inset(outLocalInsets);
}
}

View File

@@ -20,6 +20,10 @@ package android.view;
import android.annotation.Nullable;
import android.graphics.Rect;
import com.android.internal.util.Preconditions;
import java.util.Objects;
/**
* Describes a set of insets for window content.
*
@@ -27,6 +31,12 @@ import android.graphics.Rect;
* To adjust insets, use one of the supplied clone methods to obtain a new WindowInsets instance
* with the adjusted properties.</p>
*
* <p>Note: Before {@link android.os.Build.VERSION_CODES#P P}, WindowInsets instances were only
* immutable during a single layout pass (i.e. would return the same values between
* {@link View#onApplyWindowInsets} and {@link View#onLayout}, but could return other values
* otherwise). Starting with {@link android.os.Build.VERSION_CODES#P P}, WindowInsets are
* always immutable and implement equality.
*
* @see View.OnApplyWindowInsetsListener
* @see View#onApplyWindowInsets(WindowInsets)
*/
@@ -69,13 +79,14 @@ public final class WindowInsets {
public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, Rect stableInsets,
boolean isRound, boolean alwaysConsumeNavBar, DisplayCutout displayCutout) {
mSystemWindowInsetsConsumed = systemWindowInsets == null;
mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;
mSystemWindowInsets = mSystemWindowInsetsConsumed
? EMPTY_RECT : new Rect(systemWindowInsets);
mWindowDecorInsetsConsumed = windowDecorInsets == null;
mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;
mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : new Rect(windowDecorInsets);
mStableInsetsConsumed = stableInsets == null;
mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : stableInsets;
mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : new Rect(stableInsets);
mIsRound = isRound;
mAlwaysConsumeNavBar = alwaysConsumeNavBar;
@@ -535,4 +546,104 @@ public final class WindowInsets {
+ (isRound() ? " round" : "")
+ "}";
}
/**
* Returns a copy of this instance inset in the given directions.
*
* @see #inset(int, int, int, int)
* @hide
*/
public WindowInsets inset(Rect r) {
return inset(r.left, r.top, r.right, r.bottom);
}
/**
* Returns a copy of this instance inset in the given directions.
*
* This is intended for dispatching insets to areas of the window that are smaller than the
* current area.
*
* <p>Example:
* <pre>
* childView.dispatchApplyWindowInsets(insets.inset(
* childMarginLeft, childMarginTop, childMarginBottom, childMarginRight));
* </pre>
*
* @param left the amount of insets to remove from the left. Must be non-negative.
* @param top the amount of insets to remove from the top. Must be non-negative.
* @param right the amount of insets to remove from the right. Must be non-negative.
* @param bottom the amount of insets to remove from the bottom. Must be non-negative.
*
* @return the inset insets
*
* @hide pending API
*/
public WindowInsets inset(int left, int top, int right, int bottom) {
Preconditions.checkArgumentNonnegative(left);
Preconditions.checkArgumentNonnegative(top);
Preconditions.checkArgumentNonnegative(right);
Preconditions.checkArgumentNonnegative(bottom);
WindowInsets result = new WindowInsets(this);
if (!result.mSystemWindowInsetsConsumed) {
result.mSystemWindowInsets =
insetInsets(result.mSystemWindowInsets, left, top, right, bottom);
}
if (!result.mWindowDecorInsetsConsumed) {
result.mWindowDecorInsets =
insetInsets(result.mWindowDecorInsets, left, top, right, bottom);
}
if (!result.mStableInsetsConsumed) {
result.mStableInsets = insetInsets(result.mStableInsets, left, top, right, bottom);
}
if (mDisplayCutout != null) {
result.mDisplayCutout = result.mDisplayCutout.inset(left, top, right, bottom);
if (result.mDisplayCutout.isEmpty()) {
result.mDisplayCutout = null;
}
}
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !(o instanceof WindowInsets)) return false;
WindowInsets that = (WindowInsets) o;
return mIsRound == that.mIsRound
&& mAlwaysConsumeNavBar == that.mAlwaysConsumeNavBar
&& mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed
&& mWindowDecorInsetsConsumed == that.mWindowDecorInsetsConsumed
&& mStableInsetsConsumed == that.mStableInsetsConsumed
&& mDisplayCutoutConsumed == that.mDisplayCutoutConsumed
&& Objects.equals(mSystemWindowInsets, that.mSystemWindowInsets)
&& Objects.equals(mWindowDecorInsets, that.mWindowDecorInsets)
&& Objects.equals(mStableInsets, that.mStableInsets)
&& Objects.equals(mDisplayCutout, that.mDisplayCutout);
}
@Override
public int hashCode() {
return Objects.hash(mSystemWindowInsets, mWindowDecorInsets, mStableInsets, mIsRound,
mDisplayCutout, mAlwaysConsumeNavBar, mSystemWindowInsetsConsumed,
mWindowDecorInsetsConsumed, mStableInsetsConsumed, mDisplayCutoutConsumed);
}
private static Rect insetInsets(Rect insets, int left, int top, int right, int bottom) {
int newLeft = Math.max(0, insets.left - left);
int newTop = Math.max(0, insets.top - top);
int newRight = Math.max(0, insets.right - right);
int newBottom = Math.max(0, insets.bottom - bottom);
if (newLeft == left && newTop == top && newRight == right && newBottom == bottom) {
return insets;
}
return new Rect(newLeft, newTop, newRight, newBottom);
}
/**
* @return whether system window insets have been consumed.
*/
boolean isSystemWindowInsetsConsumed() {
return mSystemWindowInsetsConsumed;
}
}