Merge "Interpolate scrim radius using display shape" into sc-dev

This commit is contained in:
Lucas Dupin
2021-04-28 14:45:49 +00:00
committed by Android (Google) Code Review
4 changed files with 95 additions and 46 deletions

View File

@@ -47,9 +47,9 @@ public class ScrimDrawable extends Drawable {
private ValueAnimator mColorAnimation;
private int mMainColorTo;
private float mCornerRadius;
private Rect mBounds;
private ConcaveInfo mConcaveInfo;
private int mBottomEdgePosition;
private boolean mCornerRadiusEnabled;
public ScrimDrawable() {
mPaint = new Paint();
@@ -134,29 +134,50 @@ public class ScrimDrawable extends Drawable {
}
/**
* Enable drawable shape to have rounded corners with provided radius
* Corner radius used by either concave or convex corners.
*/
public void setRoundedCorners(float radius) {
if (radius == mCornerRadius) {
return;
}
mCornerRadius = radius;
if (mConcaveInfo != null) {
mConcaveInfo.setCornerRadius(radius);
updatePath();
}
invalidateSelf();
}
/**
* Make bottom edge concave with provided corner radius
* If we should draw a rounded rect instead of a rect.
*/
public void setBottomEdgeConcave(float radius) {
if (radius == 0) {
// Disable clipping completely when there's no radius.
mConcaveInfo = null;
public void setRoundedCornersEnabled(boolean enabled) {
if (mCornerRadiusEnabled == enabled) {
return;
}
// only rounding top corners for clip out path
float[] cornerRadii = new float[]{radius, radius, radius, radius, 0, 0, 0, 0};
mConcaveInfo = new ConcaveInfo(radius, cornerRadii);
mCornerRadiusEnabled = enabled;
invalidateSelf();
}
/**
* If we should draw a concave rounded rect instead of a rect.
*/
public void setBottomEdgeConcave(boolean enabled) {
if (enabled && mConcaveInfo != null) {
return;
}
if (!enabled) {
mConcaveInfo = null;
} else {
mConcaveInfo = new ConcaveInfo();
mConcaveInfo.setCornerRadius(mCornerRadius);
}
invalidateSelf();
}
/**
* Location of concave edge.
* @see #setBottomEdgeConcave(float)
* @see #setBottomEdgeConcave(boolean)
*/
public void setBottomEdgePosition(int y) {
if (mBottomEdgePosition == y) {
@@ -176,34 +197,35 @@ public class ScrimDrawable extends Drawable {
mPaint.setAlpha(mAlpha);
if (mConcaveInfo != null) {
drawConcave(canvas);
} else {
} else if (mCornerRadiusEnabled && mCornerRadius > 0) {
canvas.drawRoundRect(getBounds().left, getBounds().top, getBounds().right,
getBounds().bottom + mCornerRadius,
/* x radius*/ mCornerRadius, /* y radius*/ mCornerRadius, mPaint);
} else {
canvas.drawRect(getBounds().left, getBounds().top, getBounds().right,
getBounds().bottom, mPaint);
}
}
@Override
protected void onBoundsChange(Rect bounds) {
updatePath();
}
private void drawConcave(Canvas canvas) {
// checking if width of clip out path needs to change
if (mBounds == null
|| getBounds().right != mBounds.right
|| getBounds().left != mBounds.left) {
mBounds = getBounds();
updatePath();
}
canvas.clipOutPath(mConcaveInfo.mPath);
canvas.drawRect(getBounds().left, getBounds().top, getBounds().right,
mBottomEdgePosition + mConcaveInfo.mPathOverlap, mPaint);
}
private void updatePath() {
mConcaveInfo.mPath.reset();
if (mBounds == null) {
mBounds = getBounds();
if (mConcaveInfo == null) {
return;
}
mConcaveInfo.mPath.reset();
float top = mBottomEdgePosition;
float bottom = mBottomEdgePosition + mConcaveInfo.mPathOverlap;
mConcaveInfo.mPath.addRoundRect(mBounds.left, top, mBounds.right, bottom,
mConcaveInfo.mPath.addRoundRect(getBounds().left, top, getBounds().right, bottom,
mConcaveInfo.mCornerRadii, Path.Direction.CW);
}
@@ -213,13 +235,20 @@ public class ScrimDrawable extends Drawable {
}
private static class ConcaveInfo {
private final float mPathOverlap;
private float mPathOverlap;
private final float[] mCornerRadii;
private final Path mPath = new Path();
ConcaveInfo(float pathOverlap, float[] cornerRadii) {
mPathOverlap = pathOverlap;
mCornerRadii = cornerRadii;
ConcaveInfo() {
mCornerRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0};
}
public void setCornerRadius(float radius) {
mPathOverlap = radius;
mCornerRadii[0] = radius;
mCornerRadii[1] = radius;
mCornerRadii[2] = radius;
mCornerRadii[3] = radius;
}
}
}

View File

@@ -31,14 +31,12 @@ import android.os.Looper;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.DimenRes;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.systemui.R;
import java.util.concurrent.Executor;
@@ -50,9 +48,6 @@ import java.util.concurrent.Executor;
*/
public class ScrimView extends View {
@DimenRes
private static final int CORNER_RADIUS = R.dimen.notification_scrim_corner_radius;
private final Object mColorLock = new Object();
@GuardedBy("mColorLock")
@@ -301,13 +296,10 @@ public class ScrimView extends View {
* Make bottom edge concave so overlap between layers is not visible for alphas between 0 and 1
* @return height of concavity
*/
public float enableBottomEdgeConcave(boolean clipScrim) {
public void enableBottomEdgeConcave(boolean clipScrim) {
if (mDrawable instanceof ScrimDrawable) {
float radius = clipScrim ? getResources().getDimensionPixelSize(CORNER_RADIUS) : 0;
((ScrimDrawable) mDrawable).setBottomEdgeConcave(radius);
return radius;
((ScrimDrawable) mDrawable).setBottomEdgeConcave(clipScrim);
}
return 0;
}
/**
@@ -321,12 +313,11 @@ public class ScrimView extends View {
}
/**
* Enable view to have rounded corners with radius of {@link #CORNER_RADIUS}
* Enable view to have rounded corners.
*/
public void enableRoundedCorners() {
public void enableRoundedCorners(boolean enabled) {
if (mDrawable instanceof ScrimDrawable) {
int radius = getResources().getDimensionPixelSize(CORNER_RADIUS);
((ScrimDrawable) mDrawable).setRoundedCorners(radius);
((ScrimDrawable) mDrawable).setRoundedCornersEnabled(enabled);
}
}
@@ -340,4 +331,15 @@ public class ScrimView extends View {
mDrawableBounds.set((int) left, (int) top, (int) right, (int) bottom);
mDrawable.setBounds(mDrawableBounds);
}
/**
* Corner radius of both concave or convex corners.
* @see #enableRoundedCorners(boolean)
* @see #enableBottomEdgeConcave(boolean)
*/
public void setCornerRadius(int radius) {
if (mDrawable instanceof ScrimDrawable) {
((ScrimDrawable) mDrawable).setRoundedCorners(radius);
}
}
}

View File

@@ -523,12 +523,13 @@ public class NotificationPanelViewController extends PanelViewController {
private final Rect mKeyguardStatusAreaClipBounds = new Rect();
private int mOldLayoutDirection;
private NotificationShelfController mNotificationShelfController;
private int mScrimCornerRadius;
private int mScreenCornerRadius;
private final QuickAccessWalletClient mQuickAccessWalletClient;
private final Executor mUiExecutor;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
private int mScrimCornerRadius;
private KeyguardMediaController mKeyguardMediaController;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@@ -807,6 +808,10 @@ public class NotificationPanelViewController extends PanelViewController {
com.android.internal.R.dimen.status_bar_height);
mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize(
R.dimen.heads_up_status_bar_padding);
mScrimCornerRadius = mResources.getDimensionPixelSize(
R.dimen.notification_scrim_corner_radius);
mScreenCornerRadius = mResources.getDimensionPixelSize(
com.android.internal.R.dimen.rounded_corner_radius);
}
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
@@ -871,8 +876,6 @@ public class NotificationPanelViewController extends PanelViewController {
public void updateResources() {
mSplitShadeNotificationsTopPadding =
mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade);
mScrimCornerRadius =
mResources.getDimensionPixelSize(R.dimen.notification_scrim_corner_radius);
int qsWidth = mResources.getDimensionPixelSize(R.dimen.qs_panel_width);
int panelWidth = mResources.getDimensionPixelSize(R.dimen.notification_panel_width);
mShouldUseSplitNotificationShade =
@@ -2058,6 +2061,7 @@ public class NotificationPanelViewController extends PanelViewController {
int left = 0;
int right = 0;
boolean visible = qsFraction > 0 || qsPanelBottomY > 0;
int radius = mScrimCornerRadius;
if (visible || !mShouldUseSplitNotificationShade) {
if (!mShouldUseSplitNotificationShade) {
float notificationTop = mAmbientState.getStackY() - mQsNotificationTopPadding;
@@ -2065,6 +2069,8 @@ public class NotificationPanelViewController extends PanelViewController {
bottom = getView().getBottom();
left = getView().getLeft();
right = getView().getRight();
radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
Math.min(top / (float) mScrimCornerRadius, 1f));
} else {
top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
bottom = mNotificationStackScrollLayoutController.getHeight();
@@ -2076,7 +2082,7 @@ public class NotificationPanelViewController extends PanelViewController {
if (!mShouldUseSplitNotificationShade) {
// Fancy clipping for quick settings
if (mQs != null) {
mQs.setFancyClipping(top, bottom, mScrimCornerRadius, visible);
mQs.setFancyClipping(top, bottom, radius, visible);
}
// The padding on this area is large enough that we can use a cheaper clipping strategy
mKeyguardStatusAreaClipBounds.set(left, top, right, bottom);
@@ -2084,6 +2090,7 @@ public class NotificationPanelViewController extends PanelViewController {
? mKeyguardStatusAreaClipBounds : null);
}
mScrimController.setNotificationsBounds(left, top, right, bottom);
mScrimController.setScrimCornerRadius(radius);
}
private int calculateQsBottomPosition(float qsExpansionFraction) {

View File

@@ -269,7 +269,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
updateThemeColors();
behindScrim.enableBottomEdgeConcave(mClipsQsScrim);
mNotificationsScrim.enableRoundedCorners();
mNotificationsScrim.enableRoundedCorners(true);
if (mScrimBehindChangeRunnable != null) {
mScrimBehind.setChangeRunnable(mScrimBehindChangeRunnable, mMainExecutor);
@@ -294,6 +294,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mKeyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
}
/**
* Sets corner radius of scrims.
*/
public void setScrimCornerRadius(int radius) {
if (mScrimBehind == null || mNotificationsScrim == null) {
return;
}
mScrimBehind.setCornerRadius(radius);
mNotificationsScrim.setCornerRadius(radius);
}
void setScrimVisibleListener(Consumer<Integer> listener) {
mScrimVisibleListener = listener;
}