google / automotive-design-compose

Automotive Design for Compose is an extension to Jetpack Compose that allows every screen, component, and overlay of your Android App to be defined in Figma, and lets you see the latest changes to your Figma design in your app, immediately!
https://google.github.io/automotive-design-compose/
Apache License 2.0
101 stars 14 forks source link

Linear gradients are missing all color stops and causing a crash #1035

Closed iamralpht closed 2 weeks ago

iamralpht commented 2 weeks ago

Via @Heneveld, a recent regression in the Figma API, causes a crash in DesignCompose:

java.lang.IllegalArgumentException: needs >= 2 number of colors
at android.graphics.Shader.convertColors(Shader.java:190)
at android.graphics.LinearGradient.<init>(LinearGradient.java:70)
at androidx.compose.ui.graphics.AndroidShader_androidKt.ActualLinearGradientShader-VjE6UOU(AndroidShader.android.kt:39)
at androidx.compose.ui.graphics.ShaderKt.LinearGradientShader-VjE6UOU(Shader.kt:44)
at com.android.designcompose.RelativeLinearGradient.createShader-uvyYCjk(Utils.kt:815)
at androidx.compose.ui.graphics.ShaderBrush.applyTo-Pq9zytI(Brush.kt:661)
at com.android.designcompose.FrameRenderKt.render(FrameRender.kt:365)

We should not crash in this case. Either we validate that there are at least two stops in the Figma API to DCF conversion (and log if not, discarding the fill), OR we do it in Kotlin (e.g. ShaderBrush.applyTo), OR both.

rylin8 commented 2 weeks ago

The API to DCF conversion code is here: https://github.com/google/automotive-design-compose/blob/0552d72a4970346782f7766f9dd7d4dab3b6790d/crates/figma_import/src/transform_flexbox.rs#L592

rylin8 commented 2 weeks ago

The Kotlin code that creates a brush from the color stops is here https://github.com/google/automotive-design-compose/blob/0552d72a4970346782f7766f9dd7d4dab3b6790d/designcompose/src/main/java/com/android/designcompose/Utils.kt#L1234

iamralpht commented 2 weeks ago

Probably wise to do the same check for the other gradient types, too, and log & return Background::None in Rust, and log & return null in the Kotlin shader brush util.