Merge "Fix flicker when starting folding" into tm-qpr-dev
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
index 2334a4c..9421524 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
@@ -90,8 +90,13 @@
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)
@@ -116,17 +121,17 @@
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
)
}
}
@@ -234,7 +239,14 @@
* 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>
@@ -278,6 +290,17 @@
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
* if the start gradient bounds allow to see some content this could be used to make the reveal
@@ -375,6 +398,11 @@
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
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index 9cca950..523cf68 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -159,18 +159,24 @@
ensureOverlayRemoved()
val newRoot = SurfaceControlViewHost(context, context.display!!, wwm)
- val newView =
- LightRevealScrim(context, null).apply {
- revealEffect = createLightRevealEffect()
- isScrimOpaqueChangedListener = Consumer {}
- revealAmount =
- when (reason) {
- FOLD -> TRANSPARENT
- UNFOLD -> BLACK
- }
- }
-
val params = getLayoutParams()
+ val newView =
+ LightRevealScrim(
+ context,
+ attrs = null,
+ initialWidth = params.width,
+ initialHeight = params.height
+ )
+ .apply {
+ revealEffect = createLightRevealEffect()
+ isScrimOpaqueChangedListener = Consumer {}
+ revealAmount =
+ when (reason) {
+ FOLD -> TRANSPARENT
+ UNFOLD -> BLACK
+ }
+ }
+
newRoot.setView(newView, params)
if (onOverlayReady != null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
index 97fe25d..d3befb4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
@@ -20,6 +20,7 @@
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
@@ -36,7 +37,7 @@
@Before
fun setUp() {
- scrim = LightRevealScrim(context, null)
+ scrim = LightRevealScrim(context, null, DEFAULT_WIDTH, DEFAULT_HEIGHT)
scrim.isScrimOpaqueChangedListener = Consumer { opaque ->
isOpaque = opaque
}
@@ -63,4 +64,25 @@
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