Skip to content

Commit

Permalink
Fix RippleDrawables not rendering correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanmos committed Sep 6, 2023
1 parent aa1c2e1 commit b7e6b45
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ internal class Base64Serializer private constructor(
applicationContext: Context,
displayMetrics: DisplayMetrics,
drawable: Drawable,
drawableWidth: Int,
drawableHeight: Int,
imageWireframe: MobileSegment.Wireframe.ImageWireframe
) {
registerCacheForCallbacks(applicationContext)
Expand All @@ -73,6 +75,8 @@ internal class Base64Serializer private constructor(
} else {
drawableUtils.createBitmapOfApproxSizeFromDrawable(
drawable,
drawableWidth,
drawableHeight,
displayMetrics
)?.let {
shouldCacheBitmap = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
package com.datadog.android.sessionreplay.internal.recorder.base64

import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.LayerDrawable
import android.view.View
import android.widget.TextView
import androidx.annotation.MainThread
Expand Down Expand Up @@ -37,13 +40,14 @@ internal class ImageWireframeHelper(
prefix: String = DRAWABLE_CHILD_NAME
): MobileSegment.Wireframe.ImageWireframe? {
val id = uniqueIdentifierGenerator.resolveChildUniqueIdentifier(view, prefix + currentWireframeIndex)
val (currentDrawable, drawableWidth, drawableHeight) = resolveDrawableProperties(view, drawable)

@Suppress("ComplexCondition")
if (
drawable == null ||
currentDrawable == null ||
id == null ||
drawable.intrinsicWidth <= 0 ||
drawable.intrinsicHeight <= 0
drawableWidth <= 0 ||
drawableHeight <= 0
) {
return null
}
Expand All @@ -69,7 +73,9 @@ internal class ImageWireframeHelper(
base64Serializer.handleBitmap(
applicationContext = applicationContext,
displayMetrics = displayMetrics,
drawable = drawable,
drawable = currentDrawable,
drawableWidth,
drawableHeight,
imageWireframe = imageWireframe
)

Expand Down Expand Up @@ -129,6 +135,17 @@ internal class ImageWireframeHelper(
return result
}

private fun resolveDrawableProperties(view: View, drawable: Drawable?): DrawableProperties {
if (drawable == null) return DrawableProperties(null, 0, 0)

return when (drawable) {
is LayerDrawable -> resolveDrawableProperties(view, drawable.getDrawable(0))
is InsetDrawable -> resolveDrawableProperties(view, drawable.drawable)
is GradientDrawable -> DrawableProperties(drawable, view.width, view.height)
else -> DrawableProperties(drawable, drawable.intrinsicWidth, drawable.intrinsicHeight)
}
}

@Suppress("MagicNumber")
private fun convertIndexToCompoundDrawablePosition(compoundDrawableIndex: Int): CompoundDrawablePositions? {
return when (compoundDrawableIndex) {
Expand All @@ -147,6 +164,12 @@ internal class ImageWireframeHelper(
BOTTOM
}

private data class DrawableProperties(
val drawable: Drawable?,
val drawableWidth: Int,
val drawableHeight: Int
)

internal companion object {
@VisibleForTesting internal const val DRAWABLE_CHILD_NAME = "drawable"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ abstract class BaseWireframeMapper<T : View, S : MobileSegment.Wireframe>(
y = bounds.y,
width,
height,
view.background,
view.background?.constantState?.newDrawable(),
shapeStyle = null,
border = null,
prefix = PREFIX_BACKGROUND_DRAWABLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ internal class DrawableUtils(
@Suppress("ReturnCount")
internal fun createBitmapOfApproxSizeFromDrawable(
drawable: Drawable,
drawableWidth: Int,
drawableHeight: Int,
displayMetrics: DisplayMetrics,
requestedSizeInBytes: Int = MAX_BITMAP_SIZE_IN_BYTES,
config: Config = Config.ARGB_8888
): Bitmap? {
val (width, height) = getScaledWidthAndHeight(drawable, requestedSizeInBytes)
val (width, height) = getScaledWidthAndHeight(drawableWidth, drawableHeight, requestedSizeInBytes)

val bitmap = getBitmapBySize(displayMetrics, width, height, config) ?: return null
val canvas = canvasWrapper.createCanvas(bitmap) ?: return null
Expand Down Expand Up @@ -102,11 +104,12 @@ internal class DrawableUtils(
}

private fun getScaledWidthAndHeight(
drawable: Drawable,
drawableWidth: Int,
drawableHeight: Int,
requestedSizeInBytes: Int
): Pair<Int, Int> {
var width = drawable.intrinsicWidth
var height = drawable.intrinsicHeight
var width = drawableWidth
var height = drawableHeight
val sizeAfterCreation = width * height * ARGB_8888_PIXEL_SIZE_BYTES

if (sizeAfterCreation > requestedSizeInBytes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ internal class Base64SerializerTest {
whenever(
mockDrawableUtils.createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -143,6 +145,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -156,6 +160,8 @@ internal class Base64SerializerTest {
whenever(
mockDrawableUtils.createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -167,6 +173,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -180,6 +188,8 @@ internal class Base64SerializerTest {
whenever(
mockDrawableUtils.createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -191,6 +201,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -209,6 +221,8 @@ internal class Base64SerializerTest {
whenever(
mockDrawableUtils.createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -223,6 +237,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -238,6 +254,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)
}
Expand All @@ -254,6 +272,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)
}
Expand All @@ -272,12 +292,16 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

// Then
verify(mockDrawableUtils).createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -303,6 +327,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockStateListDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -320,6 +346,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockStateListDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -337,12 +365,16 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockBitmapDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

// Then
verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -361,12 +393,16 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockBitmapDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

// Then
verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable(
drawable = any(),
drawableWidth = any(),
drawableHeight = any(),
displayMetrics = any(),
requestedSizeInBytes = anyOrNull(),
config = anyOrNull()
Expand All @@ -385,6 +421,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockBitmapDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -404,6 +442,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockBitmapDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -423,6 +463,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockBitmapDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand All @@ -440,6 +482,8 @@ internal class Base64SerializerTest {
applicationContext = mockApplicationContext,
displayMetrics = mockDisplayMetrics,
drawable = mockBitmapDrawable,
drawableWidth = mockDrawable.intrinsicWidth,
drawableHeight = mockDrawable.intrinsicHeight,
imageWireframe = fakeImageWireframe
)

Expand Down
Loading

0 comments on commit b7e6b45

Please sign in to comment.