Loading packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +37 −9 Original line number Diff line number Diff line Loading @@ -90,8 +90,13 @@ object LiftReveal : LightRevealEffect { class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevealEffect { // Interpolator that reveals >80% of the content at 0.5 progress, makes revealing faster private val interpolator = PathInterpolator(/* controlX1= */ 0.4f, /* controlY1= */ 0f, /* controlX2= */ 0.2f, /* controlY2= */ 1f) private val interpolator = PathInterpolator( /* controlX1= */ 0.4f, /* controlY1= */ 0f, /* controlX2= */ 0.2f, /* controlY2= */ 1f ) override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) { val interpolatedAmount = interpolator.getInterpolation(amount) Loading @@ -116,17 +121,17 @@ class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevealEffe if (isVertical) { scrim.setRevealGradientBounds( left = scrim.width / 2 - (scrim.width / 2) * gradientBoundsAmount, left = scrim.viewWidth / 2 - (scrim.viewWidth / 2) * gradientBoundsAmount, top = 0f, right = scrim.width / 2 + (scrim.width / 2) * gradientBoundsAmount, bottom = scrim.height.toFloat() right = scrim.viewWidth / 2 + (scrim.viewWidth / 2) * gradientBoundsAmount, bottom = scrim.viewHeight.toFloat() ) } else { scrim.setRevealGradientBounds( left = 0f, top = scrim.height / 2 - (scrim.height / 2) * gradientBoundsAmount, right = scrim.width.toFloat(), bottom = scrim.height / 2 + (scrim.height / 2) * gradientBoundsAmount top = scrim.viewHeight / 2 - (scrim.viewHeight / 2) * gradientBoundsAmount, right = scrim.viewWidth.toFloat(), bottom = scrim.viewHeight / 2 + (scrim.viewHeight / 2) * gradientBoundsAmount ) } } Loading Loading @@ -234,7 +239,14 @@ class PowerButtonReveal( * transparent center. The center position, size, and stops of the gradient can be manipulated to * reveal views below the scrim as if they are being 'lit up'. */ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, attrs) { class LightRevealScrim @JvmOverloads constructor( context: Context?, attrs: AttributeSet?, initialWidth: Int? = null, initialHeight: Int? = null ) : View(context, attrs) { /** Listener that is called if the scrim's opaqueness changes */ lateinit var isScrimOpaqueChangedListener: Consumer<Boolean> Loading Loading @@ -277,6 +289,17 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, var revealGradientWidth: Float = 0f var revealGradientHeight: Float = 0f /** * Keeps the initial value until the view is measured. See [LightRevealScrim.onMeasure]. * * Needed as the view dimensions are used before the onMeasure pass happens, and without preset * width and height some flicker during fold/unfold happens. */ internal var viewWidth: Int = initialWidth ?: 0 private set internal var viewHeight: Int = initialHeight ?: 0 private set /** * Alpha of the fill that can be used in the beginning of the animation to hide the content. * Normally the gradient bounds are animated from small size so the content is not visible, but Loading Loading @@ -375,6 +398,11 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, invalidate() } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) viewWidth = measuredWidth viewHeight = measuredHeight } /** * Sets bounds for the transparent oval gradient that reveals the views below the scrim. This is * simply a helper method that sets [revealGradientCenter], [revealGradientWidth], and Loading packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt +16 −10 Original line number Diff line number Diff line Loading @@ -159,8 +159,15 @@ constructor( ensureOverlayRemoved() val newRoot = SurfaceControlViewHost(context, context.display!!, wwm) val params = getLayoutParams() val newView = LightRevealScrim(context, null).apply { LightRevealScrim( context, attrs = null, initialWidth = params.width, initialHeight = params.height ) .apply { revealEffect = createLightRevealEffect() isScrimOpaqueChangedListener = Consumer {} revealAmount = Loading @@ -170,7 +177,6 @@ constructor( } } val params = getLayoutParams() newRoot.setView(newView, params) if (onOverlayReady != null) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt +23 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.testing.AndroidTestingRunner import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before Loading @@ -36,7 +37,7 @@ class LightRevealScrimTest : SysuiTestCase() { @Before fun setUp() { scrim = LightRevealScrim(context, null) scrim = LightRevealScrim(context, null, DEFAULT_WIDTH, DEFAULT_HEIGHT) scrim.isScrimOpaqueChangedListener = Consumer { opaque -> isOpaque = opaque } Loading @@ -63,4 +64,25 @@ class LightRevealScrimTest : SysuiTestCase() { scrim.revealAmount = 0.5f assertFalse("Scrim is opaque even though it's revealed", scrim.isScrimOpaque) } @Test fun testBeforeOnMeasure_defaultDimensions() { assertThat(scrim.viewWidth).isEqualTo(DEFAULT_WIDTH) assertThat(scrim.viewHeight).isEqualTo(DEFAULT_HEIGHT) } @Test fun testAfterOnMeasure_measuredDimensions() { scrim.measure(/* widthMeasureSpec= */ exact(1), /* heightMeasureSpec= */ exact(2)) assertThat(scrim.viewWidth).isEqualTo(1) assertThat(scrim.viewHeight).isEqualTo(2) } private fun exact(value: Int) = View.MeasureSpec.makeMeasureSpec(value, View.MeasureSpec.EXACTLY) private companion object { private const val DEFAULT_WIDTH = 42 private const val DEFAULT_HEIGHT = 24 } } No newline at end of file Loading
packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +37 −9 Original line number Diff line number Diff line Loading @@ -90,8 +90,13 @@ object LiftReveal : LightRevealEffect { class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevealEffect { // Interpolator that reveals >80% of the content at 0.5 progress, makes revealing faster private val interpolator = PathInterpolator(/* controlX1= */ 0.4f, /* controlY1= */ 0f, /* controlX2= */ 0.2f, /* controlY2= */ 1f) private val interpolator = PathInterpolator( /* controlX1= */ 0.4f, /* controlY1= */ 0f, /* controlX2= */ 0.2f, /* controlY2= */ 1f ) override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) { val interpolatedAmount = interpolator.getInterpolation(amount) Loading @@ -116,17 +121,17 @@ class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevealEffe if (isVertical) { scrim.setRevealGradientBounds( left = scrim.width / 2 - (scrim.width / 2) * gradientBoundsAmount, left = scrim.viewWidth / 2 - (scrim.viewWidth / 2) * gradientBoundsAmount, top = 0f, right = scrim.width / 2 + (scrim.width / 2) * gradientBoundsAmount, bottom = scrim.height.toFloat() right = scrim.viewWidth / 2 + (scrim.viewWidth / 2) * gradientBoundsAmount, bottom = scrim.viewHeight.toFloat() ) } else { scrim.setRevealGradientBounds( left = 0f, top = scrim.height / 2 - (scrim.height / 2) * gradientBoundsAmount, right = scrim.width.toFloat(), bottom = scrim.height / 2 + (scrim.height / 2) * gradientBoundsAmount top = scrim.viewHeight / 2 - (scrim.viewHeight / 2) * gradientBoundsAmount, right = scrim.viewWidth.toFloat(), bottom = scrim.viewHeight / 2 + (scrim.viewHeight / 2) * gradientBoundsAmount ) } } Loading Loading @@ -234,7 +239,14 @@ class PowerButtonReveal( * transparent center. The center position, size, and stops of the gradient can be manipulated to * reveal views below the scrim as if they are being 'lit up'. */ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, attrs) { class LightRevealScrim @JvmOverloads constructor( context: Context?, attrs: AttributeSet?, initialWidth: Int? = null, initialHeight: Int? = null ) : View(context, attrs) { /** Listener that is called if the scrim's opaqueness changes */ lateinit var isScrimOpaqueChangedListener: Consumer<Boolean> Loading Loading @@ -277,6 +289,17 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, var revealGradientWidth: Float = 0f var revealGradientHeight: Float = 0f /** * Keeps the initial value until the view is measured. See [LightRevealScrim.onMeasure]. * * Needed as the view dimensions are used before the onMeasure pass happens, and without preset * width and height some flicker during fold/unfold happens. */ internal var viewWidth: Int = initialWidth ?: 0 private set internal var viewHeight: Int = initialHeight ?: 0 private set /** * Alpha of the fill that can be used in the beginning of the animation to hide the content. * Normally the gradient bounds are animated from small size so the content is not visible, but Loading Loading @@ -375,6 +398,11 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, invalidate() } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) viewWidth = measuredWidth viewHeight = measuredHeight } /** * Sets bounds for the transparent oval gradient that reveals the views below the scrim. This is * simply a helper method that sets [revealGradientCenter], [revealGradientWidth], and Loading
packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt +16 −10 Original line number Diff line number Diff line Loading @@ -159,8 +159,15 @@ constructor( ensureOverlayRemoved() val newRoot = SurfaceControlViewHost(context, context.display!!, wwm) val params = getLayoutParams() val newView = LightRevealScrim(context, null).apply { LightRevealScrim( context, attrs = null, initialWidth = params.width, initialHeight = params.height ) .apply { revealEffect = createLightRevealEffect() isScrimOpaqueChangedListener = Consumer {} revealAmount = Loading @@ -170,7 +177,6 @@ constructor( } } val params = getLayoutParams() newRoot.setView(newView, params) if (onOverlayReady != null) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt +23 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.testing.AndroidTestingRunner import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before Loading @@ -36,7 +37,7 @@ class LightRevealScrimTest : SysuiTestCase() { @Before fun setUp() { scrim = LightRevealScrim(context, null) scrim = LightRevealScrim(context, null, DEFAULT_WIDTH, DEFAULT_HEIGHT) scrim.isScrimOpaqueChangedListener = Consumer { opaque -> isOpaque = opaque } Loading @@ -63,4 +64,25 @@ class LightRevealScrimTest : SysuiTestCase() { scrim.revealAmount = 0.5f assertFalse("Scrim is opaque even though it's revealed", scrim.isScrimOpaque) } @Test fun testBeforeOnMeasure_defaultDimensions() { assertThat(scrim.viewWidth).isEqualTo(DEFAULT_WIDTH) assertThat(scrim.viewHeight).isEqualTo(DEFAULT_HEIGHT) } @Test fun testAfterOnMeasure_measuredDimensions() { scrim.measure(/* widthMeasureSpec= */ exact(1), /* heightMeasureSpec= */ exact(2)) assertThat(scrim.viewWidth).isEqualTo(1) assertThat(scrim.viewHeight).isEqualTo(2) } private fun exact(value: Int) = View.MeasureSpec.makeMeasureSpec(value, View.MeasureSpec.EXACTLY) private companion object { private const val DEFAULT_WIDTH = 42 private const val DEFAULT_HEIGHT = 24 } } No newline at end of file