diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java index 0a55fbe8bf75f..3c6ab34733e58 100644 --- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java @@ -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; } } } diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java index 0d9ade6da49c4..1a5c9ee25b479 100644 --- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java @@ -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); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 8574830e642ce..f3190220d970a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 0d96ead964f7f..6fb18d41e84bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -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 listener) { mScrimVisibleListener = listener; }