diff options
8 files changed, 76 insertions, 63 deletions
diff --git a/packages/SystemUI/res/layout/wireless_charging_layout.xml b/packages/SystemUI/res/layout/wireless_charging_layout.xml index 730f24ff9dd2..d82151d30b9e 100644 --- a/packages/SystemUI/res/layout/wireless_charging_layout.xml +++ b/packages/SystemUI/res/layout/wireless_charging_layout.xml @@ -22,6 +22,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + <com.android.systemui.statusbar.charging.ChargingRippleView + android:id="@+id/wireless_charging_ripple" + android:layout_width="match_parent" + android:layout_height="match_parent"/> + <!-- Circle animation --> <ImageView android:id="@+id/wireless_charging_view" diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java index 2569f7c107cb..f7beaf123b7c 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java @@ -26,7 +26,6 @@ import android.os.Message; import android.util.Log; import android.util.Slog; import android.view.Gravity; -import android.view.View; import android.view.WindowManager; /** @@ -98,8 +97,8 @@ public class WirelessChargingAnimation { private final Handler mHandler; private int mGravity; - private View mView; - private View mNextView; + private WirelessChargingLayout mView; + private WirelessChargingLayout mNextView; private WindowManager mWM; private Callback mCallback; @@ -112,7 +111,7 @@ public class WirelessChargingAnimation { mGravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER; final WindowManager.LayoutParams params = mParams; - params.height = WindowManager.LayoutParams.WRAP_CONTENT; + params.height = WindowManager.LayoutParams.MATCH_PARENT; params.width = WindowManager.LayoutParams.MATCH_PARENT; params.format = PixelFormat.TRANSLUCENT; diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java index e8407f01516b..ce0b51489490 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java @@ -20,6 +20,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; +import android.graphics.PointF; import android.graphics.drawable.Animatable; import android.util.AttributeSet; import android.util.TypedValue; @@ -29,8 +30,10 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.statusbar.charging.ChargingRippleView; import java.text.NumberFormat; @@ -38,7 +41,9 @@ import java.text.NumberFormat; * @hide */ public class WirelessChargingLayout extends FrameLayout { - public final static int UNKNOWN_BATTERY_LEVEL = -1; + public static final int UNKNOWN_BATTERY_LEVEL = -1; + private static final long RIPPLE_ANIMATION_DURATION = 2000; + private ChargingRippleView mRippleView; public WirelessChargingLayout(Context context) { super(context); @@ -120,6 +125,8 @@ public class WirelessChargingLayout extends FrameLayout { AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator); + mRippleView = findViewById(R.id.wireless_charging_ripple); + if (!showTransmittingBatteryLevel) { chargingAnimation.start(); animatorSet.start(); @@ -195,4 +202,21 @@ public class WirelessChargingLayout extends FrameLayout { animatorSetTransmitting.start(); animatorSetIcon.start(); } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (mRippleView != null) { + int width = getMeasuredWidth(); + int height = getMeasuredHeight(); + mRippleView.setColor( + Utils.getColorAttr(mRippleView.getContext(), + android.R.attr.colorAccent).getDefaultColor()); + mRippleView.setOrigin(new PointF(width / 2, height / 2)); + mRippleView.setRadius(Math.max(width, height) * 0.5f); + mRippleView.setDuration(RIPPLE_ANIMATION_DURATION); + mRippleView.startRipple(); + } + + super.onLayout(changed, left, top, right, bottom); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt index 6f80317e8f56..05af08e0287a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/ChargingRippleView.kt @@ -25,10 +25,8 @@ import android.graphics.Paint import android.graphics.PointF import android.util.AttributeSet import android.view.View -import kotlin.math.max -private const val RIPPLE_ANIMATION_DURATION: Long = 1500 -private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.3f +private const val RIPPLE_SPARKLE_STRENGTH: Float = 0.4f /** * Expanding ripple effect that shows when charging begins. @@ -39,17 +37,18 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context private val defaultColor: Int = 0xffffffff.toInt() private val ripplePaint = Paint() + var radius: Float = 0.0f + set(value) { rippleShader.radius = value } + var origin: PointF = PointF() + set(value) { rippleShader.origin = value } + var duration: Long = 1500 + init { rippleShader.color = defaultColor rippleShader.progress = 0f rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH ripplePaint.shader = rippleShader - } - - override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { - rippleShader.origin = PointF(measuredWidth / 2f, measuredHeight.toFloat()) - rippleShader.radius = max(measuredWidth, measuredHeight).toFloat() - super.onLayout(changed, left, top, right, bottom) + visibility = View.GONE } fun startRipple() { @@ -57,7 +56,7 @@ class ChargingRippleView(context: Context?, attrs: AttributeSet?) : View(context return // Ignore if ripple effect is already playing } val animator = ValueAnimator.ofFloat(0f, 1f) - animator.duration = RIPPLE_ANIMATION_DURATION + animator.duration = duration animator.addUpdateListener { animator -> val now = animator.currentPlayTime val phase = now / 30000f diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt index 5547c1e78cc4..d400205af50b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/RippleShader.kt @@ -53,7 +53,7 @@ class RippleShader internal constructor() : RuntimeShader(SHADER, false) { float s = 0.0; for (float i = 0; i < 4; i += 1) { float l = i * 0.25; - float h = l + 0.025; + float h = l + 0.005; float o = abs(sin(0.1 * PI * (t + i))); s += threshold(n + o, l, h); } @@ -97,7 +97,7 @@ class RippleShader internal constructor() : RuntimeShader(SHADER, false) { float fadeRipple = min(fadeIn, 1.-fadeOutRipple); float rippleAlpha = softRing(p, in_origin, radius, 0.5) * fadeRipple * in_color.a; - vec4 ripple = in_color * max(circle, rippleAlpha) * 0.4; + vec4 ripple = in_color * max(circle, rippleAlpha) * 0.3; return mix(ripple, vec4(sparkle), sparkle * in_sparkle_strength); }""" private const val SHADER = SHADER_UNIFORMS + SHADER_LIB + SHADER_MAIN diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt index b567ad4ccfc2..2900462c6924 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.charging import android.content.Context import android.content.res.Configuration +import android.graphics.PointF import android.util.DisplayMetrics import android.view.View import android.view.ViewGroupOverlay @@ -31,6 +32,7 @@ import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController import java.io.PrintWriter +import java.lang.Integer.max import javax.inject.Inject /*** @@ -46,7 +48,7 @@ class WiredChargingRippleController @Inject constructor( private val context: Context, private val keyguardStateController: KeyguardStateController ) { - private var pluggedIn: Boolean? = null + private var charging: Boolean? = null private val rippleEnabled: Boolean = featureFlags.isChargingRippleEnabled @VisibleForTesting var rippleView: ChargingRippleView = ChargingRippleView(context, attrs = null) @@ -55,16 +57,18 @@ class WiredChargingRippleController @Inject constructor( val batteryStateChangeCallback = object : BatteryController.BatteryStateChangeCallback { override fun onBatteryLevelChanged( level: Int, - nowPluggedIn: Boolean, - charging: Boolean + pluggedIn: Boolean, + nowCharging: Boolean ) { - if (!rippleEnabled) { + // Suppresses the ripple when it's disabled, or when the state change comes + // from wireless charging. + if (!rippleEnabled || batteryController.isWirelessCharging) { return } - val wasPluggedIn = pluggedIn - pluggedIn = nowPluggedIn + val wasCharging = charging + charging = nowCharging // Only triggers when the keyguard is active and the device is just plugged in. - if (wasPluggedIn == false && nowPluggedIn && keyguardStateController.isShowing) { + if (wasCharging == false && nowCharging && keyguardStateController.isShowing) { rippleView.startRipple() } } @@ -113,10 +117,13 @@ class WiredChargingRippleController @Inject constructor( val width = displayMetrics.widthPixels val height = displayMetrics.heightPixels if (width != rippleView.width || height != rippleView.height) { - rippleView.measure( - View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)) - rippleView.layout(0, 0, width, height) + rippleView.apply { + measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)) + layout(0, 0, width, height) + origin = PointF(width / 2f, height.toFloat()) + radius = max(width, height).toFloat() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index c83b60d07aa6..d581c4b6f9b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -184,7 +184,6 @@ import com.android.systemui.statusbar.AutoHideUiElement; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.CircleReveal; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.GestureRecorder; import com.android.systemui.statusbar.KeyboardShortcuts; @@ -2469,39 +2468,19 @@ public class StatusBar extends SystemUI implements DemoMode, protected void showChargingAnimation(int batteryLevel, int transmittingBatteryLevel, long animationDelay) { - if (mDozing || mKeyguardManager.isKeyguardLocked()) { - // on ambient or lockscreen, hide notification panel - WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null, - transmittingBatteryLevel, batteryLevel, - new WirelessChargingAnimation.Callback() { - @Override - public void onAnimationStarting() { - mNotificationShadeWindowController.setRequestTopUi(true, TAG); - CrossFadeHelper.fadeOut(mNotificationPanelViewController.getView(), 1); - } - - @Override - public void onAnimationEnded() { - CrossFadeHelper.fadeIn(mNotificationPanelViewController.getView()); - mNotificationShadeWindowController.setRequestTopUi(false, TAG); - } - }, mDozing).show(animationDelay); - } else { - // workspace - WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null, - transmittingBatteryLevel, batteryLevel, - new WirelessChargingAnimation.Callback() { - @Override - public void onAnimationStarting() { - mNotificationShadeWindowController.setRequestTopUi(true, TAG); - } + WirelessChargingAnimation.makeWirelessChargingAnimation(mContext, null, + transmittingBatteryLevel, batteryLevel, + new WirelessChargingAnimation.Callback() { + @Override + public void onAnimationStarting() { + mNotificationShadeWindowController.setRequestTopUi(true, TAG); + } - @Override - public void onAnimationEnded() { - mNotificationShadeWindowController.setRequestTopUi(false, TAG); - } - }, false).show(animationDelay); - } + @Override + public void onAnimationEnded() { + mNotificationShadeWindowController.setRequestTopUi(false, TAG); + } + }, false).show(animationDelay); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt index 3701b9127116..9ce72414d751 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt @@ -93,8 +93,8 @@ class WiredChargingRippleControllerTest : SysuiTestCase() { captor.value.onBatteryLevelChanged( unusedBatteryLevel, - true /* plugged in */, - false /* charging */) + false /* plugged in */, + true /* charging */) verify(rippleView).startRipple() } |