summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yein Jo <yeinj@google.com> 2023-02-16 18:47:36 +0000
committer Yein Jo <yeinj@google.com> 2023-02-16 18:47:36 +0000
commit6a731c2c8a12425c9f42a922383eeca46aff7342 (patch)
tree485606152377300b76a019c935d03b5e987b75c4
parentfabc17ea4e0e7a0c571034ad4a63ed0b922a8894 (diff)
Update uniform params for the tablet docking animation.
Please find the recordings in the bug attached. Bug: 269124200 Test: Manual Test: adb shell cmd statusbar docking-ripple Change-Id: I31f7baf272f67be4ab85b3e35fd0a0269cf0e0ed
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt89
-rw-r--r--packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java94
2 files changed, 162 insertions, 21 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
index ef5663fdcf6c..4c7c43548016 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
@@ -81,6 +81,87 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
}
/**
+ * Sets the fade parameters for the base ring.
+ *
+ * <p>Base ring indicates a blurred ring below the sparkle ring. See
+ * [RippleShader.baseRingFadeParams].
+ */
+ @JvmOverloads
+ fun setBaseRingFadeParams(
+ fadeInStart: Float = rippleShader.baseRingFadeParams.fadeInStart,
+ fadeInEnd: Float = rippleShader.baseRingFadeParams.fadeInEnd,
+ fadeOutStart: Float = rippleShader.baseRingFadeParams.fadeOutStart,
+ fadeOutEnd: Float = rippleShader.baseRingFadeParams.fadeOutEnd
+ ) {
+ setFadeParams(
+ rippleShader.baseRingFadeParams,
+ fadeInStart,
+ fadeInEnd,
+ fadeOutStart,
+ fadeOutEnd
+ )
+ }
+
+ /**
+ * Sets the fade parameters for the sparkle ring.
+ *
+ * <p>Sparkle ring refers to the ring that's drawn on top of the base ring. See
+ * [RippleShader.sparkleRingFadeParams].
+ */
+ @JvmOverloads
+ fun setSparkleRingFadeParams(
+ fadeInStart: Float = rippleShader.sparkleRingFadeParams.fadeInStart,
+ fadeInEnd: Float = rippleShader.sparkleRingFadeParams.fadeInEnd,
+ fadeOutStart: Float = rippleShader.sparkleRingFadeParams.fadeOutStart,
+ fadeOutEnd: Float = rippleShader.sparkleRingFadeParams.fadeOutEnd
+ ) {
+ setFadeParams(
+ rippleShader.sparkleRingFadeParams,
+ fadeInStart,
+ fadeInEnd,
+ fadeOutStart,
+ fadeOutEnd
+ )
+ }
+
+ /**
+ * Sets the fade parameters for the center fill.
+ *
+ * <p>One common use case is set all the params to 1, which completely removes the center fill.
+ * See [RippleShader.centerFillFadeParams].
+ */
+ @JvmOverloads
+ fun setCenterFillFadeParams(
+ fadeInStart: Float = rippleShader.centerFillFadeParams.fadeInStart,
+ fadeInEnd: Float = rippleShader.centerFillFadeParams.fadeInEnd,
+ fadeOutStart: Float = rippleShader.centerFillFadeParams.fadeOutStart,
+ fadeOutEnd: Float = rippleShader.centerFillFadeParams.fadeOutEnd
+ ) {
+ setFadeParams(
+ rippleShader.centerFillFadeParams,
+ fadeInStart,
+ fadeInEnd,
+ fadeOutStart,
+ fadeOutEnd
+ )
+ }
+
+ private fun setFadeParams(
+ fadeParams: RippleShader.FadeParams,
+ fadeInStart: Float,
+ fadeInEnd: Float,
+ fadeOutStart: Float,
+ fadeOutEnd: Float
+ ) {
+ with(fadeParams) {
+ this.fadeInStart = fadeInStart
+ this.fadeInEnd = fadeInEnd
+ this.fadeOutStart = fadeOutStart
+ this.fadeOutEnd = fadeOutEnd
+ }
+ }
+
+ /**
* Sets blur multiplier at start and end of the progress.
*
* <p>It interpolates between [start] and [end]. No need to set it if using default blur.
@@ -148,11 +229,11 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
}
// To reduce overdraw, we mask the effect to a circle or a rectangle that's bigger than the
// active effect area. Values here should be kept in sync with the animation implementation
- // in the ripple shader. (Twice bigger)
+ // in the ripple shader.
if (rippleShape == RippleShape.CIRCLE) {
val maskRadius = rippleShader.rippleSize.currentWidth
canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint)
- } else {
+ } else if (rippleShape == RippleShape.ELLIPSE) {
val maskWidth = rippleShader.rippleSize.currentWidth * 2
val maskHeight = rippleShader.rippleSize.currentHeight * 2
canvas.drawRect(
@@ -162,6 +243,10 @@ open class RippleView(context: Context?, attrs: AttributeSet?) : View(context, a
/* bottom= */ centerY + maskHeight,
ripplePaint
)
+ } else { // RippleShape.RoundedBox
+ // No masking for the rounded box, as it has more blur which requires larger bounds.
+ // Masking creates sharp bounds even when the masking is 4 times bigger.
+ canvas.drawPaint(ripplePaint)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
index 36103f8db8d8..cef415c8a490 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
@@ -33,7 +33,9 @@ import android.widget.TextView;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
+import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.surfaceeffects.ripple.RippleAnimationConfig;
+import com.android.systemui.surfaceeffects.ripple.RippleShader;
import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape;
import com.android.systemui.surfaceeffects.ripple.RippleView;
@@ -44,10 +46,12 @@ import java.text.NumberFormat;
*/
final class WirelessChargingLayout extends FrameLayout {
private static final long CIRCLE_RIPPLE_ANIMATION_DURATION = 1500;
- private static final long ROUNDED_BOX_RIPPLE_ANIMATION_DURATION = 1750;
+ private static final long ROUNDED_BOX_RIPPLE_ANIMATION_DURATION = 3000;
private static final int SCRIM_COLOR = 0x4C000000;
private static final int SCRIM_FADE_DURATION = 300;
private RippleView mRippleView;
+ // This is only relevant to the rounded box ripple.
+ private RippleShader.SizeAtProgress[] mSizeAtProgressArray;
WirelessChargingLayout(Context context, int transmittingBatteryLevel, int batteryLevel,
boolean isDozing, RippleShape rippleShape) {
@@ -125,20 +129,23 @@ final class WirelessChargingLayout extends FrameLayout {
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator);
- ValueAnimator scrimFadeInAnimator = ObjectAnimator.ofArgb(this,
- "backgroundColor", Color.TRANSPARENT, SCRIM_COLOR);
- scrimFadeInAnimator.setDuration(SCRIM_FADE_DURATION);
- scrimFadeInAnimator.setInterpolator(Interpolators.LINEAR);
- ValueAnimator scrimFadeOutAnimator = ObjectAnimator.ofArgb(this,
- "backgroundColor", SCRIM_COLOR, Color.TRANSPARENT);
- scrimFadeOutAnimator.setDuration(SCRIM_FADE_DURATION);
- scrimFadeOutAnimator.setInterpolator(Interpolators.LINEAR);
- scrimFadeOutAnimator.setStartDelay((rippleShape == RippleShape.CIRCLE
- ? CIRCLE_RIPPLE_ANIMATION_DURATION : ROUNDED_BOX_RIPPLE_ANIMATION_DURATION)
- - SCRIM_FADE_DURATION);
- AnimatorSet animatorSetScrim = new AnimatorSet();
- animatorSetScrim.playTogether(scrimFadeInAnimator, scrimFadeOutAnimator);
- animatorSetScrim.start();
+ // For tablet docking animation, we don't play the background scrim.
+ if (!Utilities.isTablet(context)) {
+ ValueAnimator scrimFadeInAnimator = ObjectAnimator.ofArgb(this,
+ "backgroundColor", Color.TRANSPARENT, SCRIM_COLOR);
+ scrimFadeInAnimator.setDuration(SCRIM_FADE_DURATION);
+ scrimFadeInAnimator.setInterpolator(Interpolators.LINEAR);
+ ValueAnimator scrimFadeOutAnimator = ObjectAnimator.ofArgb(this,
+ "backgroundColor", SCRIM_COLOR, Color.TRANSPARENT);
+ scrimFadeOutAnimator.setDuration(SCRIM_FADE_DURATION);
+ scrimFadeOutAnimator.setInterpolator(Interpolators.LINEAR);
+ scrimFadeOutAnimator.setStartDelay((rippleShape == RippleShape.CIRCLE
+ ? CIRCLE_RIPPLE_ANIMATION_DURATION : ROUNDED_BOX_RIPPLE_ANIMATION_DURATION)
+ - SCRIM_FADE_DURATION);
+ AnimatorSet animatorSetScrim = new AnimatorSet();
+ animatorSetScrim.playTogether(scrimFadeInAnimator, scrimFadeOutAnimator);
+ animatorSetScrim.start();
+ }
mRippleView = findViewById(R.id.wireless_charging_ripple);
mRippleView.setupShader(rippleShape);
@@ -147,7 +154,26 @@ final class WirelessChargingLayout extends FrameLayout {
if (mRippleView.getRippleShape() == RippleShape.ROUNDED_BOX) {
mRippleView.setDuration(ROUNDED_BOX_RIPPLE_ANIMATION_DURATION);
mRippleView.setSparkleStrength(0.22f);
- mRippleView.setColor(color, 28);
+ mRippleView.setColor(color, 102); // 40% of opacity.
+ mRippleView.setBaseRingFadeParams(
+ /* fadeInStart = */ 0f,
+ /* fadeInEnd = */ 0f,
+ /* fadeOutStart = */ 0.2f,
+ /* fadeOutEnd= */ 0.47f
+ );
+ mRippleView.setSparkleRingFadeParams(
+ /* fadeInStart = */ 0f,
+ /* fadeInEnd = */ 0f,
+ /* fadeOutStart = */ 0.2f,
+ /* fadeOutEnd= */ 1f
+ );
+ mRippleView.setCenterFillFadeParams(
+ /* fadeInStart = */ 0f,
+ /* fadeInEnd = */ 0f,
+ /* fadeOutStart = */ 0f,
+ /* fadeOutEnd= */ 0.2f
+ );
+ mRippleView.setBlur(6.5f, 2.5f);
} else {
mRippleView.setDuration(CIRCLE_RIPPLE_ANIMATION_DURATION);
mRippleView.setColor(color, RippleAnimationConfig.RIPPLE_DEFAULT_ALPHA);
@@ -246,9 +272,7 @@ final class WirelessChargingLayout extends FrameLayout {
int height = getMeasuredHeight();
mRippleView.setCenter(width * 0.5f, height * 0.5f);
if (mRippleView.getRippleShape() == RippleShape.ROUNDED_BOX) {
- // Those magic numbers are introduced for visual polish. This aspect ratio maps with
- // the tablet's docking station.
- mRippleView.setMaxSize(width * 1.36f, height * 1.46f);
+ updateRippleSizeAtProgressList(width, height);
} else {
float maxSize = Math.max(width, height);
mRippleView.setMaxSize(maxSize, maxSize);
@@ -257,4 +281,36 @@ final class WirelessChargingLayout extends FrameLayout {
super.onLayout(changed, left, top, right, bottom);
}
+
+ private void updateRippleSizeAtProgressList(float width, float height) {
+ if (mSizeAtProgressArray == null) {
+ float maxSize = Math.max(width, height);
+ mSizeAtProgressArray = new RippleShader.SizeAtProgress[] {
+ // Those magic numbers are introduced for visual polish. It starts from a pill
+ // shape and expand to a full circle.
+ new RippleShader.SizeAtProgress(0f, 0f, 0f),
+ new RippleShader.SizeAtProgress(0.3f, width * 0.4f, height * 0.4f),
+ new RippleShader.SizeAtProgress(1f, maxSize, maxSize)
+ };
+ } else {
+ // Same multipliers, just need to recompute with the new width and height.
+ RippleShader.SizeAtProgress first = mSizeAtProgressArray[0];
+ first.setT(0f);
+ first.setWidth(0f);
+ first.setHeight(0f);
+
+ RippleShader.SizeAtProgress second = mSizeAtProgressArray[1];
+ second.setT(0.3f);
+ second.setWidth(width * 0.4f);
+ second.setHeight(height * 0.4f);
+
+ float maxSize = Math.max(width, height);
+ RippleShader.SizeAtProgress last = mSizeAtProgressArray[2];
+ last.setT(1f);
+ last.setWidth(maxSize);
+ last.setHeight(maxSize);
+ }
+
+ mRippleView.setSizeAtProgresses(mSizeAtProgressArray);
+ }
}