Modified the way the notifications clip to the boundary am: 07045f95e0

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14936977

Change-Id: I346533b0dc16aae58acc916b532d31c7f6ba6bf0
This commit is contained in:
Selim Cinek
2021-06-16 13:30:55 +00:00
committed by Automerger Merge Worker
11 changed files with 142 additions and 203 deletions

View File

@@ -330,30 +330,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
} }
} }
@Override
public void setDistanceToTopRoundness(float distanceToTopRoundness) {
super.setDistanceToTopRoundness(distanceToTopRoundness);
mBackgroundNormal.setDistanceToTopRoundness(distanceToTopRoundness);
}
/** Sets whether this view is the last notification in a section. */
@Override
public void setLastInSection(boolean lastInSection) {
if (lastInSection != mLastInSection) {
super.setLastInSection(lastInSection);
mBackgroundNormal.setLastInSection(lastInSection);
}
}
/** Sets whether this view is the first notification in a section. */
@Override
public void setFirstInSection(boolean firstInSection) {
if (firstInSection != mFirstInSection) {
super.setFirstInSection(firstInSection);
mBackgroundNormal.setFirstInSection(firstInSection);
}
}
/** /**
* Set an override tint color that is used for the background. * Set an override tint color that is used for the background.
* *

View File

@@ -846,8 +846,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
updateClickAndFocus(); updateClickAndFocus();
if (mNotificationParent != null) { if (mNotificationParent != null) {
setOverrideTintColor(NO_COLOR, 0.0f); setOverrideTintColor(NO_COLOR, 0.0f);
// Let's reset the distance to top roundness, as this isn't applied to group children
setDistanceToTopRoundness(NO_ROUNDNESS);
mNotificationParent.updateBackgroundForGroupState(); mNotificationParent.updateBackgroundForGroupState();
} }
updateBackgroundClipping(); updateBackgroundClipping();
@@ -3036,24 +3034,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|| mExpandAnimationRunning || mChildIsExpanding)); || mExpandAnimationRunning || mChildIsExpanding));
} }
@Override
public boolean topAmountNeedsClipping() {
if (isGroupExpanded()) {
return true;
}
if (isGroupExpansionChanging()) {
return true;
}
if (getShowingLayout().shouldClipToRounding(true /* topRounded */,
false /* bottomRounded */)) {
return true;
}
if (mGuts != null && mGuts.getAlpha() != 0.0f) {
return true;
}
return false;
}
@Override @Override
protected boolean childNeedsClipping(View child) { protected boolean childNeedsClipping(View child) {
if (child instanceof NotificationContentView) { if (child instanceof NotificationContentView) {

View File

@@ -75,16 +75,13 @@ public abstract class ExpandableOutlineView extends ExpandableView {
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself. * it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
*/ */
protected boolean mShouldTranslateContents; protected boolean mShouldTranslateContents;
private boolean mTopAmountRounded;
private float mDistanceToTopRoundness = -1;
private float[] mTmpCornerRadii = new float[8]; private float[] mTmpCornerRadii = new float[8];
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() { private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
@Override @Override
public void getOutline(View view, Outline outline) { public void getOutline(View view, Outline outline) {
if (!mCustomOutline && getCurrentTopRoundness() == 0.0f if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
&& getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners) {
&& !mTopAmountRounded) {
int translation = mShouldTranslateContents ? (int) getTranslation() : 0; int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
int left = Math.max(translation, 0); int left = Math.max(translation, 0);
int top = mClipTopAmount + mBackgroundTop; int top = mClipTopAmount + mBackgroundTop;
@@ -168,33 +165,15 @@ public abstract class ExpandableOutlineView extends ExpandableView {
@Override @Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
canvas.save(); canvas.save();
Path intersectPath = null;
if (mTopAmountRounded && topAmountNeedsClipping()) {
int left = (int) (- mExtraWidthForClipping / 2.0f);
int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
int right = getWidth() + (int) (mExtraWidthForClipping + left);
int bottom = (int) Math.max(mMinimumHeightForClipping,
Math.max(getActualHeight() - mClipBottomAmount, top + mOutlineRadius));
getRoundedRectPath(left, top, right, bottom, mOutlineRadius, 0.0f, mClipPath);
intersectPath = mClipPath;
}
boolean clipped = false;
if (childNeedsClipping(child)) { if (childNeedsClipping(child)) {
Path clipPath = getCustomClipPath(child); Path clipPath = getCustomClipPath(child);
if (clipPath == null) { if (clipPath == null) {
clipPath = getClipPath(false /* ignoreTranslation */); clipPath = getClipPath(false /* ignoreTranslation */);
} }
if (clipPath != null) { if (clipPath != null) {
if (intersectPath != null) {
clipPath.op(intersectPath, Path.Op.INTERSECT);
}
canvas.clipPath(clipPath); canvas.clipPath(clipPath);
clipped = true;
} }
} }
if (!clipped && intersectPath != null) {
canvas.clipPath(intersectPath);
}
boolean result = super.drawChild(canvas, child, drawingTime); boolean result = super.drawChild(canvas, child, drawingTime);
canvas.restore(); canvas.restore();
return result; return result;
@@ -212,24 +191,10 @@ public abstract class ExpandableOutlineView extends ExpandableView {
invalidate(); invalidate();
} }
@Override
public void setDistanceToTopRoundness(float distanceToTopRoundness) {
super.setDistanceToTopRoundness(distanceToTopRoundness);
if (distanceToTopRoundness != mDistanceToTopRoundness) {
mTopAmountRounded = distanceToTopRoundness >= 0;
mDistanceToTopRoundness = distanceToTopRoundness;
applyRoundness();
}
}
protected boolean childNeedsClipping(View child) { protected boolean childNeedsClipping(View child) {
return false; return false;
} }
public boolean topAmountNeedsClipping() {
return true;
}
protected boolean isClippingNeeded() { protected boolean isClippingNeeded() {
return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ; return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
} }
@@ -272,11 +237,6 @@ public abstract class ExpandableOutlineView extends ExpandableView {
} }
public float getCurrentBackgroundRadiusTop() { public float getCurrentBackgroundRadiusTop() {
// If this view is top amount notification view, it should always has round corners on top.
// It will be applied with applyRoundness()
if (mTopAmountRounded) {
return mOutlineRadius;
}
return getCurrentTopRoundness() * mOutlineRadius; return getCurrentTopRoundness() * mOutlineRadius;
} }

View File

@@ -46,7 +46,6 @@ import java.util.List;
public abstract class ExpandableView extends FrameLayout implements Dumpable { public abstract class ExpandableView extends FrameLayout implements Dumpable {
private static final String TAG = "ExpandableView"; private static final String TAG = "ExpandableView";
public static final float NO_ROUNDNESS = -1;
protected OnHeightChangedListener mOnHeightChangedListener; protected OnHeightChangedListener mOnHeightChangedListener;
private int mActualHeight; private int mActualHeight;
protected int mClipTopAmount; protected int mClipTopAmount;
@@ -192,14 +191,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
} }
} }
/**
* Set the distance to the top roundness, from where we should start clipping a value above
* or equal to 0 is the effective distance, and if a value below 0 is received, there should
* be no clipping.
*/
public void setDistanceToTopRoundness(float distanceToTopRoundness) {
}
public void setActualHeight(int actualHeight) { public void setActualHeight(int actualHeight) {
setActualHeight(actualHeight, true /* notifyListeners */); setActualHeight(actualHeight, true /* notifyListeners */);
} }

View File

@@ -42,10 +42,8 @@ public class NotificationBackgroundView extends View {
private int mActualHeight; private int mActualHeight;
private int mClipBottomAmount; private int mClipBottomAmount;
private int mTintColor; private int mTintColor;
private float[] mCornerRadii = new float[8]; private final float[] mCornerRadii = new float[8];
private boolean mBottomIsRounded; private boolean mBottomIsRounded;
private boolean mLastInSection;
private boolean mFirstInSection;
private int mBackgroundTop; private int mBackgroundTop;
private boolean mBottomAmountClips = true; private boolean mBottomAmountClips = true;
private boolean mExpandAnimationRunning; private boolean mExpandAnimationRunning;
@@ -53,9 +51,6 @@ public class NotificationBackgroundView extends View {
private int mDrawableAlpha = 255; private int mDrawableAlpha = 255;
private boolean mIsPressedAllowed; private boolean mIsPressedAllowed;
private boolean mTopAmountRounded;
private float mDistanceToTopRoundness;
public NotificationBackgroundView(Context context, AttributeSet attrs) { public NotificationBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mDontModifyCorners = getResources().getBoolean( mDontModifyCorners = getResources().getBoolean(
@@ -90,15 +85,6 @@ public class NotificationBackgroundView extends View {
left = (int) ((getWidth() - mActualWidth) / 2.0f); left = (int) ((getWidth() - mActualWidth) / 2.0f);
right = (int) (left + mActualWidth); right = (int) (left + mActualWidth);
} }
if (mTopAmountRounded) {
int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness);
if (clipTop >= 0 || !mFirstInSection) {
top += clipTop;
}
if (clipTop >= 0 && !mLastInSection) {
bottom += clipTop;
}
}
drawable.setBounds(left, top, right, bottom); drawable.setBounds(left, top, right, bottom);
drawable.draw(canvas); drawable.draw(canvas);
} }
@@ -180,14 +166,6 @@ public class NotificationBackgroundView extends View {
invalidate(); invalidate();
} }
public void setDistanceToTopRoundness(float distanceToTopRoundness) {
if (distanceToTopRoundness != mDistanceToTopRoundness) {
mTopAmountRounded = distanceToTopRoundness >= 0;
mDistanceToTopRoundness = distanceToTopRoundness;
invalidate();
}
}
@Override @Override
public boolean hasOverlappingRendering() { public boolean hasOverlappingRendering() {
@@ -246,18 +224,6 @@ public class NotificationBackgroundView extends View {
} }
} }
/** Sets whether this background belongs to the last notification in a section. */
public void setLastInSection(boolean lastInSection) {
mLastInSection = lastInSection;
invalidate();
}
/** Sets whether this background belongs to the first notification in a section. */
public void setFirstInSection(boolean firstInSection) {
mFirstInSection = firstInSection;
invalidate();
}
private void updateBackgroundRadii() { private void updateBackgroundRadii() {
if (mDontModifyCorners) { if (mDontModifyCorners) {
return; return;

View File

@@ -75,7 +75,6 @@ public class AmbientState {
private int mExpandAnimationTopChange; private int mExpandAnimationTopChange;
private ExpandableNotificationRow mExpandingNotification; private ExpandableNotificationRow mExpandingNotification;
private float mHideAmount; private float mHideAmount;
private float mNotificationScrimTop;
private boolean mAppearing; private boolean mAppearing;
private float mPulseHeight = MAX_PULSE_HEIGHT; private float mPulseHeight = MAX_PULSE_HEIGHT;
private float mDozeAmount = 0.0f; private float mDozeAmount = 0.0f;
@@ -256,20 +255,6 @@ public class AmbientState {
return mHideAmount; return mHideAmount;
} }
/**
* Set y position of top of notifications background scrim, relative to top of screen.
*/
public void setNotificationScrimTop(float notificationScrimTop) {
mNotificationScrimTop = notificationScrimTop;
}
/**
* @return Y position of top of notifications background scrim, relative to top of screen.
*/
public float getNotificationScrimTop() {
return mNotificationScrimTop;
}
public void setHideSensitive(boolean hideSensitive) { public void setHideSensitive(boolean hideSensitive) {
mHideSensitive = hideSensitive; mHideSensitive = hideSensitive;
} }

View File

@@ -40,6 +40,7 @@ import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Outline; import android.graphics.Outline;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
@@ -453,6 +454,27 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private NotificationStackScrollLayoutController mController; private NotificationStackScrollLayoutController mController;
private boolean mKeyguardMediaControllorVisible; private boolean mKeyguardMediaControllorVisible;
/**
* The clip path used to clip the view in a rounded way.
*/
private final Path mRoundedClipPath = new Path();
/**
* Should we use rounded rect clipping right now
*/
private boolean mShouldUseRoundedRectClipping = false;
private int mRoundedRectClippingLeft;
private int mRoundedRectClippingTop;
private int mRoundedRectClippingBottom;
private int mRoundedRectClippingRight;
private float[] mBgCornerRadii = new float[8];
/**
* Are we launching a notification right now
*/
private boolean mLaunchingNotification;
private NotificationEntry mTopHeadsUpEntry; private NotificationEntry mTopHeadsUpEntry;
private long mNumHeadsUp; private long mNumHeadsUp;
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler; private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
@@ -1017,33 +1039,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void onPreDrawDuringAnimation() { private void onPreDrawDuringAnimation() {
mShelf.updateAppearance(); mShelf.updateAppearance();
updateClippingToTopRoundedCorner();
if (!mNeedsAnimation && !mChildrenUpdateRequested) { if (!mNeedsAnimation && !mChildrenUpdateRequested) {
updateBackground(); updateBackground();
} }
} }
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateClippingToTopRoundedCorner() {
Float clipStart = mAmbientState.getNotificationScrimTop();
Float clipEnd = clipStart + mCornerRadius;
boolean first = true;
for (int i = 0; i < getChildCount(); i++) {
ExpandableView child = (ExpandableView) getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
float start = child.getTranslationY();
float end = start + child.getActualHeight();
boolean clip = clipStart > start && clipStart < end
|| clipEnd >= start && clipEnd <= end;
clip &= !(first && mScrollAdapter.isScrolledToTop());
child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0)
: ExpandableView.NO_ROUNDNESS);
first = false;
}
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void updateScrollStateForAddedChildren() { private void updateScrollStateForAddedChildren() {
if (mChildrenToAddAnimated.isEmpty()) { if (mChildrenToAddAnimated.isEmpty()) {
@@ -1601,6 +1601,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
Resources res = getResources(); Resources res = getResources();
mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res); mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
updateUseRoundedRectClipping();
mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height); mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
float densityScale = res.getDisplayMetrics().density; float densityScale = res.getDisplayMetrics().density;
mSwipeHelper.setDensityScale(densityScale); mSwipeHelper.setDensityScale(densityScale);
@@ -2818,6 +2819,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void applyExpandAnimationParams(ExpandAnimationParameters params) { public void applyExpandAnimationParams(ExpandAnimationParameters params) {
mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange()); mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange());
// Disable clipping for launches
setLaunchingNotification(params != null);
requestChildrenUpdate(); requestChildrenUpdate();
} }
@@ -2901,7 +2905,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mAnimationEvents.clear(); mAnimationEvents.clear();
updateBackground(); updateBackground();
updateViewShadows(); updateViewShadows();
updateClippingToTopRoundedCorner();
} else { } else {
applyCurrentState(); applyCurrentState();
} }
@@ -3795,6 +3798,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateNotificationAnimationStates(); updateNotificationAnimationStates();
updateChronometers(); updateChronometers();
requestChildrenUpdate(); requestChildrenUpdate();
updateUseRoundedRectClipping();
} }
} }
@@ -4015,7 +4019,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
setAnimationRunning(false); setAnimationRunning(false);
updateBackground(); updateBackground();
updateViewShadows(); updateViewShadows();
updateClippingToTopRoundedCorner();
} }
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4550,6 +4553,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void setQsExpansionFraction(float qsExpansionFraction) { public void setQsExpansionFraction(float qsExpansionFraction) {
mQsExpansionFraction = qsExpansionFraction; mQsExpansionFraction = qsExpansionFraction;
updateUseRoundedRectClipping();
// If notifications are scrolled, // If notifications are scrolled,
// clear out scrollY by the time we push notifications offscreen // clear out scrollY by the time we push notifications offscreen
@@ -5191,6 +5195,69 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mScrollListener = listener; mScrollListener = listener;
} }
/**
* Set rounded rect clipping bounds on this view.
*/
public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
int bottomRadius) {
if (mRoundedRectClippingLeft == left && mRoundedRectClippingRight == right
&& mRoundedRectClippingBottom == bottom && mRoundedRectClippingTop == top
&& mBgCornerRadii[0] == topRadius && mBgCornerRadii[5] == bottomRadius) {
return;
}
mRoundedRectClippingLeft = left;
mRoundedRectClippingTop = top;
mRoundedRectClippingBottom = bottom;
mRoundedRectClippingRight = right;
mBgCornerRadii[0] = topRadius;
mBgCornerRadii[1] = topRadius;
mBgCornerRadii[2] = topRadius;
mBgCornerRadii[3] = topRadius;
mBgCornerRadii[4] = bottomRadius;
mBgCornerRadii[5] = bottomRadius;
mBgCornerRadii[6] = bottomRadius;
mBgCornerRadii[7] = bottomRadius;
mRoundedClipPath.reset();
mRoundedClipPath.addRoundRect(left, top, right, bottom, mBgCornerRadii, Path.Direction.CW);
if (mShouldUseRoundedRectClipping) {
invalidate();
}
}
/**
* Set if we're launching a notification right now.
*/
private void setLaunchingNotification(boolean launching) {
if (launching == mLaunchingNotification) {
return;
}
mLaunchingNotification = launching;
updateUseRoundedRectClipping();
}
/**
* Should we use rounded rect clipping
*/
private void updateUseRoundedRectClipping() {
// We don't want to clip notifications when QS is expanded, because incoming heads up on
// the bottom would be clipped otherwise
boolean qsAllowsClipping = mQsExpansionFraction < 0.5f || mShouldUseSplitNotificationShade;
boolean clip = !mLaunchingNotification && mIsExpanded && qsAllowsClipping;
if (clip != mShouldUseRoundedRectClipping) {
mShouldUseRoundedRectClipping = clip;
invalidate();
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (mShouldUseRoundedRectClipping) {
// Let's clip rounded.
canvas.clipPath(mRoundedClipPath);
}
super.dispatchDraw(canvas);
}
/** /**
* A listener that is notified when the empty space below the notifications is clicked on * A listener that is notified when the empty space below the notifications is clicked on
*/ */

View File

@@ -822,10 +822,20 @@ public class NotificationStackScrollLayoutController {
return mView.isLayoutRtl(); return mView.isLayoutRtl();
} }
/**
* @return the left of the view.
*/
public int getLeft() { public int getLeft() {
return mView.getLeft(); return mView.getLeft();
} }
/**
* @return the top of the view.
*/
public int getTop() {
return mView.getTop();
}
public float getTranslationX() { public float getTranslationX() {
return mView.getTranslationX(); return mView.getTranslationX();
} }
@@ -1439,6 +1449,14 @@ public class NotificationStackScrollLayoutController {
mView.setOnScrollListener(listener); mView.setOnScrollListener(listener);
} }
/**
* Set rounded rect clipping bounds on this view.
*/
public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
int bottomRadius) {
mView.setRoundedClippingBounds(left, top, right, bottom, topRadius, bottomRadius);
}
/** /**
* Enum for UiEvent logged from this class * Enum for UiEvent logged from this class
*/ */

View File

@@ -158,7 +158,7 @@ public class StackScrollAlgorithm {
AmbientState ambientState) { AmbientState ambientState) {
float drawStart = ambientState.isOnKeyguard() ? 0 float drawStart = ambientState.isOnKeyguard() ? 0
: ambientState.getStackY() - ambientState.getScrollY(); : ambientState.getStackY() - ambientState.getScrollY();
float clipStart = ambientState.getNotificationScrimTop(); float clipStart = 0;
int childCount = algorithmState.visibleChildren.size(); int childCount = algorithmState.visibleChildren.size();
boolean firstHeadsUp = true; boolean firstHeadsUp = true;
for (int i = 0; i < childCount; i++) { for (int i = 0; i < childCount; i++) {

View File

@@ -2228,14 +2228,13 @@ public class NotificationPanelViewController extends PanelViewController {
* and QS state. * and QS state.
*/ */
private void setQSClippingBounds() { private void setQSClippingBounds() {
int top = 0; int top;
int bottom = 0; int bottom;
int left = 0; int left;
int right = 0; int right;
final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction()); final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction());
final boolean visible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0) final boolean qsVisible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0);
&& !mShouldUseSplitNotificationShade;
if (!mShouldUseSplitNotificationShade) { if (!mShouldUseSplitNotificationShade) {
if (mTransitioningToFullShadeProgress > 0.0f) { if (mTransitioningToFullShadeProgress > 0.0f) {
@@ -2244,7 +2243,6 @@ public class NotificationPanelViewController extends PanelViewController {
top = mTransitionToFullShadeQSPosition; top = mTransitionToFullShadeQSPosition;
} else { } else {
final float notificationTop = getQSEdgePosition(); final float notificationTop = getQSEdgePosition();
mAmbientState.setNotificationScrimTop(notificationTop);
top = (int) (isOnKeyguard() ? Math.min(qsPanelBottomY, notificationTop) top = (int) (isOnKeyguard() ? Math.min(qsPanelBottomY, notificationTop)
: notificationTop); : notificationTop);
} }
@@ -2252,8 +2250,7 @@ public class NotificationPanelViewController extends PanelViewController {
// notification bounds should take full screen width regardless of insets // notification bounds should take full screen width regardless of insets
left = 0; left = 0;
right = getView().getRight() + mDisplayRightInset; right = getView().getRight() + mDisplayRightInset;
} else if (qsPanelBottomY > 0) { // so bounds are empty on lockscreen } else {
mAmbientState.setNotificationScrimTop(mSplitShadeNotificationsTopPadding);
top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding); top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
bottom = mNotificationStackScrollLayoutController.getHeight(); bottom = mNotificationStackScrollLayoutController.getHeight();
left = mNotificationStackScrollLayoutController.getLeft(); left = mNotificationStackScrollLayoutController.getLeft();
@@ -2261,17 +2258,17 @@ public class NotificationPanelViewController extends PanelViewController {
} }
// top should never be lower than bottom, otherwise it will be invisible. // top should never be lower than bottom, otherwise it will be invisible.
top = Math.min(top, bottom); top = Math.min(top, bottom);
applyQSClippingBounds(left, top, right, bottom, visible); applyQSClippingBounds(left, top, right, bottom, qsVisible);
} }
private void applyQSClippingBounds(int left, int top, int right, int bottom, private void applyQSClippingBounds(int left, int top, int right, int bottom,
boolean visible) { boolean qsVisible) {
if (!mAnimateNextNotificationBounds || mKeyguardStatusAreaClipBounds.isEmpty()) { if (!mAnimateNextNotificationBounds || mKeyguardStatusAreaClipBounds.isEmpty()) {
if (mQsClippingAnimation != null) { if (mQsClippingAnimation != null) {
// update the end position of the animator // update the end position of the animator
mQsClippingAnimationEndBounds.set(left, top, right, bottom); mQsClippingAnimationEndBounds.set(left, top, right, bottom);
} else { } else {
applyQSClippingImmediately(left, top, right, bottom, visible); applyQSClippingImmediately(left, top, right, bottom, qsVisible);
} }
} else { } else {
mQsClippingAnimationEndBounds.set(left, top, right, bottom); mQsClippingAnimationEndBounds.set(left, top, right, bottom);
@@ -2295,7 +2292,7 @@ public class NotificationPanelViewController extends PanelViewController {
int animBottom = (int) MathUtils.lerp(startBottom, int animBottom = (int) MathUtils.lerp(startBottom,
mQsClippingAnimationEndBounds.bottom, fraction); mQsClippingAnimationEndBounds.bottom, fraction);
applyQSClippingImmediately(animLeft, animTop, animRight, animBottom, applyQSClippingImmediately(animLeft, animTop, animRight, animBottom,
visible /* visible */); qsVisible /* qsVisible */);
}); });
mQsClippingAnimation.addListener(new AnimatorListenerAdapter() { mQsClippingAnimation.addListener(new AnimatorListenerAdapter() {
@Override @Override
@@ -2310,7 +2307,7 @@ public class NotificationPanelViewController extends PanelViewController {
} }
private void applyQSClippingImmediately(int left, int top, int right, int bottom, private void applyQSClippingImmediately(int left, int top, int right, int bottom,
boolean visible) { boolean qsVisible) {
// Fancy clipping for quick settings // Fancy clipping for quick settings
int radius = mScrimCornerRadius; int radius = mScrimCornerRadius;
int statusBarClipTop = 0; int statusBarClipTop = 0;
@@ -2318,19 +2315,34 @@ public class NotificationPanelViewController extends PanelViewController {
if (!mShouldUseSplitNotificationShade) { if (!mShouldUseSplitNotificationShade) {
// The padding on this area is large enough that we can use a cheaper clipping strategy // The padding on this area is large enough that we can use a cheaper clipping strategy
mKeyguardStatusAreaClipBounds.set(left, top, right, bottom); mKeyguardStatusAreaClipBounds.set(left, top, right, bottom);
clipStatusView = visible; clipStatusView = qsVisible;
radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius, radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
Math.min(top / (float) mScrimCornerRadius, 1f)); Math.min(top / (float) mScrimCornerRadius, 1f));
statusBarClipTop = top - mKeyguardStatusBar.getTop(); statusBarClipTop = top - mKeyguardStatusBar.getTop();
} }
if (mQs != null) { if (mQs != null) {
mQs.setFancyClipping(top, bottom, radius, visible); mQs.setFancyClipping(top, bottom, radius, qsVisible
&& !mShouldUseSplitNotificationShade);
} }
mKeyguardStatusViewController.setClipBounds( mKeyguardStatusViewController.setClipBounds(
clipStatusView ? mKeyguardStatusAreaClipBounds : null); clipStatusView ? mKeyguardStatusAreaClipBounds : null);
if (!qsVisible && mShouldUseSplitNotificationShade) {
// On the lockscreen when qs isn't visible, we don't want the bounds of the shade to
// be visible, otherwise you can see the bounds once swiping up to see bouncer
mScrimController.setNotificationsBounds(0, 0, 0, 0);
} else {
mScrimController.setNotificationsBounds(left, top, right, bottom); mScrimController.setNotificationsBounds(left, top, right, bottom);
}
mScrimController.setScrimCornerRadius(radius); mScrimController.setScrimCornerRadius(radius);
mKeyguardStatusBar.setTopClipping(statusBarClipTop); mKeyguardStatusBar.setTopClipping(statusBarClipTop);
int nsslLeft = left - mNotificationStackScrollLayoutController.getLeft();
int nsslRight = right - mNotificationStackScrollLayoutController.getLeft();
int nsslTop = top - mNotificationStackScrollLayoutController.getTop();
int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop();
int bottomRadius = mShouldUseSplitNotificationShade ? radius : 0;
mNotificationStackScrollLayoutController.setRoundedClippingBounds(
nsslLeft, nsslTop, nsslRight, nsslBottom, radius, bottomRadius);
} }
private float getQSEdgePosition() { private float getQSEdgePosition() {

View File

@@ -84,7 +84,6 @@ import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager; import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.QSDetailDisplayer; import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.FeatureFlags;
@@ -675,21 +674,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
verify(mTapAgainViewController).show(); verify(mTapAgainViewController).show();
} }
@Test
public void testNotificationClipping_isAlignedWithNotificationScrimInSplitShade() {
mStatusBarStateController.setState(SHADE);
QS qs = mock(QS.class);
when(qs.getHeader()).thenReturn(mock(View.class));
mNotificationPanelViewController.mQs = qs;
enableSplitShade();
// hacky way to refresh notification scrim top with non-zero qsPanelBottom value
mNotificationPanelViewController.setTransitionToFullShadeAmount(200, false, 0);
verify(mAmbientState)
.setNotificationScrimTop(NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE);
}
private FalsingManager.FalsingTapListener getFalsingTapListener() { private FalsingManager.FalsingTapListener getFalsingTapListener() {
for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) { for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
listener.onViewAttachedToWindow(mView); listener.onViewAttachedToWindow(mView);