Skip to content

Commit

Permalink
RUM-6195: Add cache key to ImageWireframeHelper
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanmos committed Dec 5, 2024
1 parent 8743eb1 commit 56c49e9
Show file tree
Hide file tree
Showing 17 changed files with 247 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ internal class ChipWireframeMapper(
height = view.chipDrawable.intrinsicHeight,
usePIIPlaceholder = false,
drawable = view.chipDrawable,
resourceIdCacheKey = null,
asyncJobStatusCallback = asyncJobStatusCallback
)
backgroundWireframe?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.isNull
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
Expand Down Expand Up @@ -176,7 +176,8 @@ class ChipWireframeMapperTest {
clipping = isNull(),
shapeStyle = isNull(),
border = isNull(),
prefix = any()
prefix = any(),
resourceIdCacheKey = anyOrNull()
)
}

Expand Down
4 changes: 2 additions & 2 deletions features/dd-sdk-android-session-replay/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ data class com.datadog.android.sessionreplay.utils.GlobalBounds
constructor(Long, Long, Long, Long)
interface com.datadog.android.sessionreplay.utils.ImageWireframeHelper
fun createImageWireframeByBitmap(Long, GlobalBounds, android.graphics.Bitmap, Float, Boolean, com.datadog.android.sessionreplay.ImagePrivacy, AsyncJobStatusCallback, com.datadog.android.sessionreplay.model.MobileSegment.WireframeClip? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeStyle? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeBorder? = null): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe?
fun createImageWireframeByDrawable(android.view.View, com.datadog.android.sessionreplay.ImagePrivacy, Int, Long, Long, Int, Int, Boolean, android.graphics.drawable.Drawable, com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier = DefaultDrawableCopier(), AsyncJobStatusCallback, com.datadog.android.sessionreplay.model.MobileSegment.WireframeClip? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeStyle? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeBorder? = null, String? = DRAWABLE_CHILD_NAME): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe?
fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, AsyncJobStatusCallback): MutableList<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
fun createImageWireframeByDrawable(android.view.View, com.datadog.android.sessionreplay.ImagePrivacy, Int, Long, Long, Int, Int, Boolean, android.graphics.drawable.Drawable, com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier = DefaultDrawableCopier(), AsyncJobStatusCallback, com.datadog.android.sessionreplay.model.MobileSegment.WireframeClip? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeStyle? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeBorder? = null, String? = DRAWABLE_CHILD_NAME, String?): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe?
fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, String?, AsyncJobStatusCallback): MutableList<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
companion object
open class com.datadog.android.sessionreplay.utils.LegacyDrawableToColorMapper : DrawableToColorMapper
constructor(List<DrawableToColorMapper> = emptyList())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1584,17 +1584,17 @@ public final class com/datadog/android/sessionreplay/utils/GlobalBounds {

public abstract interface class com/datadog/android/sessionreplay/utils/ImageWireframeHelper {
public static final field Companion Lcom/datadog/android/sessionreplay/utils/ImageWireframeHelper$Companion;
public abstract fun createCompoundDrawableWireframes (Landroid/widget/TextView;Lcom/datadog/android/sessionreplay/recorder/MappingContext;ILcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;)Ljava/util/List;
public abstract fun createCompoundDrawableWireframes (Landroid/widget/TextView;Lcom/datadog/android/sessionreplay/recorder/MappingContext;ILjava/lang/String;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;)Ljava/util/List;
public abstract fun createImageWireframeByBitmap (JLcom/datadog/android/sessionreplay/utils/GlobalBounds;Landroid/graphics/Bitmap;FZLcom/datadog/android/sessionreplay/ImagePrivacy;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/sessionreplay/model/MobileSegment$WireframeClip;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeBorder;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe;
public abstract fun createImageWireframeByDrawable (Landroid/view/View;Lcom/datadog/android/sessionreplay/ImagePrivacy;IJJIIZLandroid/graphics/drawable/Drawable;Lcom/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/sessionreplay/model/MobileSegment$WireframeClip;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeBorder;Ljava/lang/String;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe;
public abstract fun createImageWireframeByDrawable (Landroid/view/View;Lcom/datadog/android/sessionreplay/ImagePrivacy;IJJIIZLandroid/graphics/drawable/Drawable;Lcom/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/sessionreplay/model/MobileSegment$WireframeClip;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeBorder;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe;
}

public final class com/datadog/android/sessionreplay/utils/ImageWireframeHelper$Companion {
}

public final class com/datadog/android/sessionreplay/utils/ImageWireframeHelper$DefaultImpls {
public static synthetic fun createImageWireframeByBitmap$default (Lcom/datadog/android/sessionreplay/utils/ImageWireframeHelper;JLcom/datadog/android/sessionreplay/utils/GlobalBounds;Landroid/graphics/Bitmap;FZLcom/datadog/android/sessionreplay/ImagePrivacy;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/sessionreplay/model/MobileSegment$WireframeClip;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeBorder;ILjava/lang/Object;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe;
public static synthetic fun createImageWireframeByDrawable$default (Lcom/datadog/android/sessionreplay/utils/ImageWireframeHelper;Landroid/view/View;Lcom/datadog/android/sessionreplay/ImagePrivacy;IJJIIZLandroid/graphics/drawable/Drawable;Lcom/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/sessionreplay/model/MobileSegment$WireframeClip;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeBorder;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe;
public static synthetic fun createImageWireframeByDrawable$default (Lcom/datadog/android/sessionreplay/utils/ImageWireframeHelper;Landroid/view/View;Lcom/datadog/android/sessionreplay/ImagePrivacy;IJJIIZLandroid/graphics/drawable/Drawable;Lcom/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/sessionreplay/model/MobileSegment$WireframeClip;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;Lcom/datadog/android/sessionreplay/model/MobileSegment$ShapeBorder;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe;
}

public class com/datadog/android/sessionreplay/utils/LegacyDrawableToColorMapper : com/datadog/android/sessionreplay/utils/DrawableToColorMapper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ internal abstract class CheckableTextViewMapper<T>(
border = null,
usePIIPlaceholder = true,
clipping = MobileSegment.WireframeClip(),
resourceIdCacheKey = null,
asyncJobStatusCallback = asyncJobStatusCallback
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ internal open class SwitchCompatMapper(
shapeStyle = null,
border = null,
usePIIPlaceholder = true,
resourceIdCacheKey = null,
asyncJobStatusCallback = asyncJobStatusCallback
)
}
Expand Down Expand Up @@ -141,6 +142,7 @@ internal open class SwitchCompatMapper(
border = null,
usePIIPlaceholder = true,
clipping = null,
resourceIdCacheKey = null,
asyncJobStatusCallback = asyncJobStatusCallback
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ internal class DefaultImageWireframeHelper(
clipping: MobileSegment.WireframeClip?,
shapeStyle: MobileSegment.ShapeStyle?,
border: MobileSegment.ShapeBorder?,
prefix: String?
prefix: String?,
resourceIdCacheKey: String?
): MobileSegment.Wireframe? {
val id = viewIdentifierResolver.resolveChildUniqueIdentifier(view, prefix + currentWireframeIndex)
val drawableProperties = resolveDrawableProperties(
Expand Down Expand Up @@ -204,6 +205,7 @@ internal class DefaultImageWireframeHelper(
drawableCopier = drawableCopier,
drawableWidth = width,
drawableHeight = height,
resourceIdCacheKey = resourceIdCacheKey,
resourceResolverCallback = object : ResourceResolverCallback {
override fun onSuccess(resourceId: String) {
populateResourceIdInWireframe(resourceId, imageWireframe)
Expand All @@ -225,6 +227,7 @@ internal class DefaultImageWireframeHelper(
textView: TextView,
mappingContext: MappingContext,
prevWireframeIndex: Int,
resourceIdCacheKey: String?,
asyncJobStatusCallback: AsyncJobStatusCallback
): MutableList<MobileSegment.Wireframe> {
val result = mutableListOf<MobileSegment.Wireframe>()
Expand Down Expand Up @@ -265,6 +268,7 @@ internal class DefaultImageWireframeHelper(
border = null,
usePIIPlaceholder = true,
clipping = MobileSegment.WireframeClip(),
resourceIdCacheKey = resourceIdCacheKey,
asyncJobStatusCallback = asyncJobStatusCallback
)?.let { resultWireframe ->
result.add(resultWireframe)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ internal class ResourceResolver(
drawableCopier: DrawableCopier,
drawableWidth: Int,
drawableHeight: Int,
resourceIdCacheKey: String?,
resourceResolverCallback: ResourceResolverCallback
) {
bitmapCachesManager.registerCallbacks(applicationContext)

val resourceId = tryToGetResourceFromCache(drawable = originalDrawable)
val resourceId = tryToGetResourceFromCache(drawable = originalDrawable, key = resourceIdCacheKey)

if (resourceId != null) {
// if we got here it means we saw the bitmap before,
Expand Down Expand Up @@ -115,6 +116,7 @@ internal class ResourceResolver(
drawableHeight = drawableHeight,
displayMetrics = displayMetrics,
bitmapFromDrawable = bitmapFromDrawable,
resourceIdCacheKey = resourceIdCacheKey,
resolveResourceCallback = object : ResolveResourceCallback {
override fun onResolved(resourceId: String, resourceData: ByteArray) {
resourceItemCreationHandler.queueItem(resourceId, resourceData)
Expand All @@ -141,12 +143,14 @@ internal class ResourceResolver(
drawableHeight: Int,
displayMetrics: DisplayMetrics,
bitmapFromDrawable: Bitmap?,
resourceIdCacheKey: String?,
resolveResourceCallback: ResolveResourceCallback
) {
val handledBitmap = if (bitmapFromDrawable != null) {
tryToGetBitmapFromBitmapDrawable(
drawable = drawable as BitmapDrawable,
bitmapFromDrawable = bitmapFromDrawable,
resourceIdCacheKey = resourceIdCacheKey,
resolveResourceCallback = resolveResourceCallback
)
} else {
Expand All @@ -160,6 +164,7 @@ internal class ResourceResolver(
drawableWidth = drawableWidth,
drawableHeight = drawableHeight,
displayMetrics = displayMetrics,
resourceIdCacheKey = resourceIdCacheKey,
resolveResourceCallback = resolveResourceCallback
)
}
Expand Down Expand Up @@ -195,6 +200,7 @@ internal class ResourceResolver(
bitmap: Bitmap,
compressedBitmapBytes: ByteArray,
shouldCacheBitmap: Boolean,
resourceIdCacheKey: String?,
resolveResourceCallback: ResolveResourceCallback
) {
// failed to get image data
Expand All @@ -217,6 +223,7 @@ internal class ResourceResolver(
shouldCacheBitmap = shouldCacheBitmap,
bitmap = bitmap,
resourceId = resourceId,
resourceIdCacheKey = resourceIdCacheKey,
drawable = drawable
)

Expand All @@ -227,13 +234,16 @@ internal class ResourceResolver(
shouldCacheBitmap: Boolean,
bitmap: Bitmap,
resourceId: String,
resourceIdCacheKey: String?,
drawable: Drawable
) {
if (shouldCacheBitmap) {
bitmapCachesManager.putInBitmapPool(bitmap)
}

val key = bitmapCachesManager.generateResourceKeyFromDrawable(drawable) ?: return
val key = resourceIdCacheKey
?: bitmapCachesManager.generateResourceKeyFromDrawable(drawable)
?: return
bitmapCachesManager.putInResourceCache(key, resourceId)
}

Expand All @@ -244,6 +254,7 @@ internal class ResourceResolver(
drawableWidth: Int,
drawableHeight: Int,
displayMetrics: DisplayMetrics,
resourceIdCacheKey: String?,
resolveResourceCallback: ResolveResourceCallback
) {
drawableUtils.createBitmapOfApproxSizeFromDrawable(
Expand All @@ -268,6 +279,7 @@ internal class ResourceResolver(
bitmap = bitmap,
compressedBitmapBytes = compressedBitmapBytes,
shouldCacheBitmap = true,
resourceIdCacheKey = resourceIdCacheKey,
resolveResourceCallback = resolveResourceCallback
)
}
Expand All @@ -285,6 +297,7 @@ internal class ResourceResolver(
private fun tryToGetBitmapFromBitmapDrawable(
drawable: BitmapDrawable,
bitmapFromDrawable: Bitmap,
resourceIdCacheKey: String?,
resolveResourceCallback: ResolveResourceCallback
): Bitmap? {
val scaledBitmap = drawableUtils.createScaledBitmap(bitmapFromDrawable)
Expand Down Expand Up @@ -314,17 +327,21 @@ internal class ResourceResolver(
bitmap = scaledBitmap,
compressedBitmapBytes = compressedBitmapBytes,
shouldCacheBitmap = shouldCacheBitmap,
resourceIdCacheKey = resourceIdCacheKey,
resolveResourceCallback = resolveResourceCallback
)

return scaledBitmap
}

private fun tryToGetResourceFromCache(
drawable: Drawable
drawable: Drawable,
key: String?
): String? {
val key = bitmapCachesManager.generateResourceKeyFromDrawable(drawable) ?: return null
return bitmapCachesManager.getFromResourceCache(key)
val cacheKey = key
?: bitmapCachesManager.generateResourceKeyFromDrawable(drawable)
?: return null
return bitmapCachesManager.getFromResourceCache(cacheKey)
}

private fun shouldUseDrawableBitmap(drawable: BitmapDrawable): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ abstract class BaseAsyncBackgroundWireframeMapper<in T : View> internal construc
clipping = MobileSegment.WireframeClip(),
shapeStyle = null,
border = null,
prefix = PREFIX_BACKGROUND_DRAWABLE
prefix = PREFIX_BACKGROUND_DRAWABLE,
resourceIdCacheKey = null
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ open class ImageViewMapper : BaseAsyncBackgroundWireframeMapper<ImageView> {
clipping = clipping,
shapeStyle = null,
border = null,
prefix = ImageWireframeHelper.DRAWABLE_CHILD_NAME
prefix = ImageWireframeHelper.DRAWABLE_CHILD_NAME,
resourceIdCacheKey = null
)?.let {
wireframes.add(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ open class TextViewMapper<in T : TextView>(
viewBoundsResolver: ViewBoundsResolver,
drawableToColorMapper: DrawableToColorMapper
) : BaseAsyncBackgroundWireframeMapper<T>(
viewIdentifierResolver,
colorStringFormatter,
viewBoundsResolver,
drawableToColorMapper
viewIdentifierResolver = viewIdentifierResolver,
colorStringFormatter = colorStringFormatter,
viewBoundsResolver = viewBoundsResolver,
drawableToColorMapper = drawableToColorMapper
) {

@UiThread
Expand All @@ -54,24 +54,25 @@ open class TextViewMapper<in T : TextView>(

val density = mappingContext.systemInformation.screenDensity
val viewGlobalBounds = viewBoundsResolver.resolveViewGlobalBounds(
view,
density
view = view,
screenDensity = density
)

wireframes.add(
createTextWireframe(
view,
mappingContext,
viewGlobalBounds
textView = view,
mappingContext = mappingContext,
viewGlobalBounds = viewGlobalBounds
)
)

wireframes.addAll(
mappingContext.imageWireframeHelper.createCompoundDrawableWireframes(
view,
mappingContext,
wireframes.size,
asyncJobStatusCallback
textView = view,
mappingContext = mappingContext,
prevWireframeIndex = wireframes.size,
resourceIdCacheKey = null,
asyncJobStatusCallback = asyncJobStatusCallback
)
)

Expand Down
Loading

0 comments on commit 56c49e9

Please sign in to comment.