From 8b0ea4aee41eb3bea19023334810265f8e0c4b99 Mon Sep 17 00:00:00 2001 From: jonathanmos <48201295+jonathanmos@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:06:50 +0200 Subject: [PATCH 1/9] RUM-6195: Add cache key to ImageWireframeHelper --- .../api/apiSurface | 4 +- .../DefaultImageWireframeHelperTest.kt | 284 ++++++++++++++++-- 2 files changed, 264 insertions(+), 24 deletions(-) diff --git a/features/dd-sdk-android-session-replay/api/apiSurface b/features/dd-sdk-android-session-replay/api/apiSurface index ef2ead17ba..1f8358d242 100644 --- a/features/dd-sdk-android-session-replay/api/apiSurface +++ b/features/dd-sdk-android-session-replay/api/apiSurface @@ -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, String?): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe? - fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, String?, AsyncJobStatusCallback): MutableList + 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? = null): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe? + fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, AsyncJobStatusCallback): MutableList companion object open class com.datadog.android.sessionreplay.utils.LegacyDrawableToColorMapper : DrawableToColorMapper constructor(List = emptyList()) diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt index 196ff22dc7..f98dd73453 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt @@ -173,15 +173,6 @@ internal class DefaultImageWireframeHelperTest { ) ).thenReturn(fakeGeneratedIdentifier) - whenever( - mockViewUtilsInternal.resolveCompoundDrawableBounds( - view = any(), - drawable = any(), - pixelsDensity = any(), - position = any() - ) - ).thenReturn(fakeBounds) - testedHelper = DefaultImageWireframeHelper( logger = mockLogger, resourceResolver = mockResourceResolver, @@ -503,7 +494,26 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not return image wireframe W createImageWireframeByDrawable { usePIIPlaceholder and MASK_NONE }`() { + fun `M return content placeholder W createImageWireframeByBitmap() { ImagePrivacy MASK_ALL }`() { + // When + val wireframe = testedHelper.createImageWireframeByBitmap( + id = fakeViewId, + bitmap = mockBitmap, + density = fakeDensity, + imagePrivacy = ImagePrivacy.MASK_ALL, + isContextualImage = false, + globalBounds = fakeBounds, + shapeStyle = null, + border = null, + asyncJobStatusCallback = mockAsyncJobStatusCallback + ) + + // Then + assertThat(wireframe).isInstanceOf(MobileSegment.Wireframe.PlaceholderWireframe::class.java) + } + + @Test + fun `M not return image wireframe W createImageWireframe(usePIIPlaceholder = true) { ImagePrivacy MASK_NONE }`() { // When val wireframe = testedHelper.createImageWireframeByDrawable( view = mockView, @@ -526,7 +536,26 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return null W createImageWireframeByDrawable { application context is null }`() { + fun `M not return image wireframe W createImageWireframe { ImagePrivacy MASK_LARGE_ONLY & isContextual image}`() { + // When + val wireframe = testedHelper.createImageWireframeByBitmap( + id = fakeViewId, + bitmap = mockBitmap, + density = fakeDensity, + imagePrivacy = ImagePrivacy.MASK_LARGE_ONLY, + isContextualImage = true, + globalBounds = fakeBounds, + shapeStyle = null, + border = null, + asyncJobStatusCallback = mockAsyncJobStatusCallback + ) + + // Then + assertThat(wireframe).isInstanceOf(MobileSegment.Wireframe.PlaceholderWireframe::class.java) + } + + @Test + fun `M return null W createImageWireframe() { application context is null }`() { // Given whenever(mockView.context.applicationContext).thenReturn(null) @@ -552,7 +581,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M send telemetry W createImageWireframeByDrawable { application context is null }`() { + fun `M send telemetry W createImageWireframeByDrawable() { application context is null }`() { // Given whenever(mockView.context.applicationContext).thenReturn(null) @@ -582,7 +611,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M log error W createImageWireframeByDrawable { resources is null }`() { + fun `M log error W createImageWireframeByDrawable() { resources is null }`() { // Given whenever(mockView.resources).thenReturn(null) @@ -612,7 +641,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return null W createImageWireframeByDrawable { id is null }`() { + fun `M return null W createImageWireframeByDrawable() { id is null }`() { // Given whenever(mockViewIdentifierResolver.resolveChildUniqueIdentifier(any(), any())) .thenReturn(null) @@ -640,7 +669,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return null W createImageWireframeByDrawable { drawable has no width }`() { + fun `M return null W createImageWireframeByDrawable() { drawable has no width }`() { // When val wireframe = testedHelper.createImageWireframeByDrawable( view = mockView, @@ -663,7 +692,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return null W createImageWireframeByDrawable { drawable has no height }`() { + fun `M return null W createImageWireframeByDrawable() { drawable has no height }`() { // When val wireframe = testedHelper.createImageWireframeByDrawable( view = mockView, @@ -686,7 +715,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return wireframe W createImageWireframeByDrawable`( + fun `M return wireframe W createImageWireframeByDrawable()`( @Mock mockShapeStyle: MobileSegment.ShapeStyle, @Mock mockBorder: MobileSegment.ShapeBorder, @Mock stubWireframeClip: MobileSegment.WireframeClip @@ -761,7 +790,200 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M resolve view width and height W createImageWireframeByDrawable { RippleDrawable }`( + fun `M return wireframe W createImageWireframeByBitmap()`( + @Mock mockShapeStyle: MobileSegment.ShapeStyle, + @Mock mockBorder: MobileSegment.ShapeBorder, + @Mock stubWireframeClip: MobileSegment.WireframeClip + ) { + // Given + whenever( + mockResourceResolver.resolveResourceId( + bitmap = any(), + resourceResolverCallback = any() + ) + ).thenAnswer { + val callback = it.arguments[1] as ResourceResolverCallback + callback.onSuccess(fakeResourceId) + } + + val expectedWireframe = MobileSegment.Wireframe.ImageWireframe( + id = fakeGeneratedIdentifier, + x = fakeBounds.x, + y = fakeBounds.y, + width = fakeBounds.width, + height = fakeBounds.height, + shapeStyle = mockShapeStyle, + border = mockBorder, + resourceId = fakeResourceId, + clip = stubWireframeClip, + isEmpty = false + ) + + // When + val wireframe = testedHelper.createImageWireframeByBitmap( + id = fakeGeneratedIdentifier, + imagePrivacy = ImagePrivacy.MASK_LARGE_ONLY, + density = fakeDensity, + globalBounds = fakeBounds, + bitmap = mockBitmap, + shapeStyle = mockShapeStyle, + border = mockBorder, + asyncJobStatusCallback = mockAsyncJobStatusCallback, + isContextualImage = false, + clipping = stubWireframeClip + ) + + // Then + verify(mockResourceResolver).resolveResourceId( + bitmap = any(), + resourceResolverCallback = any() + ) + verify(mockAsyncJobStatusCallback).jobStarted() + verify(mockAsyncJobStatusCallback).jobFinished() + verifyNoMoreInteractions(mockAsyncJobStatusCallback) + assertThat(wireframe).isEqualTo(expectedWireframe) + } + + // endregion + + // region createCompoundDrawableWireframes + + @Test + fun `M return empty list W createCompoundDrawableWireframes() { no compound drawables }`() { + // Given + whenever(mockTextView.compoundDrawables) + .thenReturn(arrayOf(null, null, null, null)) + + // When + val wireframes = testedHelper.createCompoundDrawableWireframes( + textView = mockTextView, + mappingContext = mockMappingContext, + prevWireframeIndex = 0, + customResourceIdCacheKey = null, + asyncJobStatusCallback = mockAsyncJobStatusCallback + ) + + // Then + verifyNoInteractions(mockAsyncJobStatusCallback) + assertThat(wireframes).isEmpty() + } + + @Test + fun `M return wireframe W createCompoundDrawableWireframes()`() { + // Given + whenever( + mockViewUtilsInternal.resolveCompoundDrawableBounds( + view = any(), + drawable = any(), + pixelsDensity = any(), + position = any() + ) + ).thenReturn(fakeBounds) + val fakeDrawables = arrayOf(null, mockDrawable, null, null) + whenever(mockTextView.compoundDrawables) + .thenReturn(fakeDrawables) + + // When + val wireframes = testedHelper.createCompoundDrawableWireframes( + textView = mockTextView, + mappingContext = mockMappingContext, + prevWireframeIndex = 0, + customResourceIdCacheKey = null, + asyncJobStatusCallback = mockAsyncJobStatusCallback + ) + wireframes[0] as MobileSegment.Wireframe.ImageWireframe + + // Then + val argumentCaptor = argumentCaptor() + + verify(mockResourceResolver).resolveResourceId( + resources = any(), + applicationContext = any(), + displayMetrics = any(), + originalDrawable = any(), + drawableCopier = any(), + drawableWidth = any(), + drawableHeight = any(), + customResourceIdCacheKey = anyOrNull(), + resourceResolverCallback = argumentCaptor.capture() + ) + argumentCaptor.allValues.forEach { + it.onSuccess(fakeResourceId) + } + verify(mockAsyncJobStatusCallback).jobStarted() + verify(mockAsyncJobStatusCallback).jobFinished() + assertThat(wireframes.size).isEqualTo(1) + } + + @Test + fun `M return multiple wireframes W createCompoundDrawableWireframes() { multiple drawables }`() { + // Given + whenever( + mockViewUtilsInternal.resolveCompoundDrawableBounds( + view = any(), + drawable = any(), + pixelsDensity = any(), + position = any() + ) + ) + .thenReturn(fakeBounds) + val fakeDrawables = arrayOf(null, mockDrawable, null, mockDrawable) + whenever(mockTextView.compoundDrawables) + .thenReturn(fakeDrawables) + + // When + val wireframes = testedHelper.createCompoundDrawableWireframes( + textView = mockTextView, + mappingContext = mockMappingContext, + prevWireframeIndex = 0, + customResourceIdCacheKey = null, + asyncJobStatusCallback = mockAsyncJobStatusCallback + ) + wireframes[0] as MobileSegment.Wireframe.ImageWireframe + + // Then + val argumentCaptor = argumentCaptor() + verify(mockResourceResolver, times(2)).resolveResourceId( + resources = any(), + applicationContext = any(), + displayMetrics = any(), + originalDrawable = any(), + drawableCopier = any(), + drawableWidth = any(), + drawableHeight = any(), + customResourceIdCacheKey = anyOrNull(), + resourceResolverCallback = argumentCaptor.capture() + ) + argumentCaptor.allValues.forEach { + it.onSuccess(fakeResourceId) + } + verify(mockAsyncJobStatusCallback, times(2)).jobStarted() + verify(mockAsyncJobStatusCallback, times(2)).jobFinished() + assertThat(wireframes.size).isEqualTo(2) + } + + @Test + fun `M skip invalid elements W createCompoundDrawableWireframes() { invalid indices }`() { + // Given + whenever(mockTextView.compoundDrawables) + .thenReturn(arrayOf(null, null, null, null, null, null)) + + // When + val wireframes = testedHelper.createCompoundDrawableWireframes( + textView = mockTextView, + mappingContext = mockMappingContext, + prevWireframeIndex = 0, + customResourceIdCacheKey = null, + asyncJobStatusCallback = mockAsyncJobStatusCallback + ) + + // Then + verifyNoInteractions(mockAsyncJobStatusCallback) + assertThat(wireframes).isEmpty() + } + + @Test + fun `M resolve view width and height W createImageWireframe() { RippleDrawable }`( @Mock mockDrawable: RippleDrawable, @Mock mockInsetDrawable: InsetDrawable, @Mock mockGradientDrawable: GradientDrawable, @@ -809,7 +1031,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M resolve drawable width and height W createImageWireframeByDrawable { TextView }`() { + fun `M resolve drawable width and height W createImageWireframe() { TextView }`() { // When testedHelper.createImageWireframeByDrawable( view = mockView, @@ -845,7 +1067,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not try to resolve bitmap W createImageWireframeByDrawable { PII image }`( + fun `M not try to resolve bitmap W createImageWireframe() { PII image }`( forge: Forge, @Mock mockResources: Resources, @Mock mockDisplayMetrics: DisplayMetrics, @@ -893,7 +1115,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M try to resolve bitmap W createImageWireframeByDrawable { non-PII image }`() { + fun `M try to resolve bitmap W createImageWireframe() { non-PII image }`() { // Given whenever(mockImageTypeResolver.isDrawablePII(any(), any())).thenReturn(false) @@ -929,7 +1151,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return content placeholder W createImageWireframeByDrawable { PII image }`() { + fun `M return content placeholder W createImageWireframe() { PII image }`() { // Given whenever(mockImageTypeResolver.isDrawablePII(any(), any())).thenReturn(true) @@ -968,6 +1190,15 @@ internal class DefaultImageWireframeHelperTest { whenever(mockTextView.compoundDrawables) .thenReturn(arrayOf(mockDrawable, mockDrawable, mockDrawable, mockDrawable)) + whenever( + mockViewUtilsInternal.resolveCompoundDrawableBounds( + view = any(), + drawable = any(), + pixelsDensity = any(), + position = any() + ) + ).thenReturn(fakeBounds) + // When testedHelper.createCompoundDrawableWireframes( textView = mockTextView, @@ -1022,6 +1253,15 @@ internal class DefaultImageWireframeHelperTest { whenever(mockTextView.compoundDrawables) .thenReturn(fakeDrawables) + whenever( + mockViewUtilsInternal.resolveCompoundDrawableBounds( + view = any(), + drawable = any(), + pixelsDensity = any(), + position = any() + ) + ).thenReturn(fakeBounds) + // When val wireframes = testedHelper.createCompoundDrawableWireframes( textView = mockTextView, From 48a9ce32b8f1583becdaf68634021791cb60e86b Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Thu, 5 Dec 2024 17:53:40 +0100 Subject: [PATCH 2/9] Expose internal classes for usage in RN --- .../api/apiSurface | 18 ++++++---- .../api/dd-sdk-android-session-replay.api | 28 ++++++++------- .../internal/DefaultRecorderProvider.kt | 4 ++- .../mapper/CheckableTextViewMapper.kt | 2 +- .../recorder/mapper/SwitchCompatMapper.kt | 2 +- .../resources/DefaultImageWireframeHelper.kt | 1 + .../recorder/resources/ResourceResolver.kt | 14 ++++---- .../internal/utils/DrawableUtils.kt | 22 +++++------- .../BaseAsyncBackgroundWireframeMapper.kt | 35 ++++++++++++++++--- .../recorder/mapper/ImageViewMapper.kt | 15 +++++--- .../resources/DefaultDrawableCopier.kt | 4 +-- .../recorder/resources/DrawableCopier.kt | 4 +-- .../utils/ImageWireframeHelper.kt | 4 +-- .../mapper/BaseCheckableTextViewMapperTest.kt | 2 +- .../resources/ResourceResolverTest.kt | 14 ++------ .../internal/utils/DrawableUtilsTest.kt | 31 ++++++++-------- .../recorder/mapper/ImageViewMapperTest.kt | 7 +++- 17 files changed, 119 insertions(+), 88 deletions(-) rename features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/{internal => }/recorder/resources/DefaultDrawableCopier.kt (83%) rename features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/{internal => }/recorder/resources/DrawableCopier.kt (84%) diff --git a/features/dd-sdk-android-session-replay/api/apiSurface b/features/dd-sdk-android-session-replay/api/apiSurface index 1f8358d242..a9cf3af341 100644 --- a/features/dd-sdk-android-session-replay/api/apiSurface +++ b/features/dd-sdk-android-session-replay/api/apiSurface @@ -59,10 +59,6 @@ interface com.datadog.android.sessionreplay.internal.recorder.obfuscator.StringO fun obfuscate(String): String companion object fun getStringObfuscator(): StringObfuscator -class com.datadog.android.sessionreplay.internal.recorder.resources.DefaultDrawableCopier : DrawableCopier - override fun copy(android.graphics.drawable.Drawable, android.content.res.Resources): android.graphics.drawable.Drawable? -interface com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier - fun copy(android.graphics.drawable.Drawable, android.content.res.Resources): android.graphics.drawable.Drawable? data class com.datadog.android.sessionreplay.recorder.MappingContext constructor(SystemInformation, com.datadog.android.sessionreplay.utils.ImageWireframeHelper, com.datadog.android.sessionreplay.TextAndInputPrivacy, com.datadog.android.sessionreplay.ImagePrivacy, Boolean = false) interface com.datadog.android.sessionreplay.recorder.OptionSelectorDetector @@ -70,7 +66,11 @@ interface com.datadog.android.sessionreplay.recorder.OptionSelectorDetector data class com.datadog.android.sessionreplay.recorder.SystemInformation constructor(com.datadog.android.sessionreplay.utils.GlobalBounds, Int = Configuration.ORIENTATION_UNDEFINED, Float, String? = null) abstract class com.datadog.android.sessionreplay.recorder.mapper.BaseAsyncBackgroundWireframeMapper : BaseWireframeMapper + constructor(com.datadog.android.sessionreplay.utils.ViewIdentifierResolver, com.datadog.android.sessionreplay.utils.ColorStringFormatter, com.datadog.android.sessionreplay.utils.ViewBoundsResolver, com.datadog.android.sessionreplay.utils.DrawableToColorMapper) override fun map(T, com.datadog.android.sessionreplay.recorder.MappingContext, com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback, com.datadog.android.api.InternalLogger): List + protected open fun resolveViewBackground(android.view.View, com.datadog.android.sessionreplay.recorder.MappingContext, com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback, com.datadog.android.api.InternalLogger): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe? + protected open fun resolveBackgroundAsShapeWireframe(android.view.View, com.datadog.android.sessionreplay.utils.GlobalBounds, Int, Int, com.datadog.android.sessionreplay.model.MobileSegment.ShapeStyle?): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe.ShapeWireframe? + protected open fun resolveBackgroundAsImageWireframe(android.view.View, com.datadog.android.sessionreplay.utils.GlobalBounds, Int, Int, com.datadog.android.sessionreplay.recorder.MappingContext, com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe? companion object open class com.datadog.android.sessionreplay.recorder.mapper.BaseViewGroupMapper : BaseAsyncBackgroundWireframeMapper, TraverseAllChildrenMapper constructor(com.datadog.android.sessionreplay.utils.ViewIdentifierResolver, com.datadog.android.sessionreplay.utils.ColorStringFormatter, com.datadog.android.sessionreplay.utils.ViewBoundsResolver, com.datadog.android.sessionreplay.utils.DrawableToColorMapper) @@ -83,7 +83,7 @@ class com.datadog.android.sessionreplay.recorder.mapper.EditTextMapper : TextVie override fun resolveCapturedText(android.widget.EditText, com.datadog.android.sessionreplay.TextAndInputPrivacy, Boolean): String companion object open class com.datadog.android.sessionreplay.recorder.mapper.ImageViewMapper : BaseAsyncBackgroundWireframeMapper - constructor(com.datadog.android.sessionreplay.utils.ViewIdentifierResolver, com.datadog.android.sessionreplay.utils.ColorStringFormatter, com.datadog.android.sessionreplay.utils.ViewBoundsResolver, com.datadog.android.sessionreplay.utils.DrawableToColorMapper) + constructor(com.datadog.android.sessionreplay.utils.ViewIdentifierResolver, com.datadog.android.sessionreplay.utils.ColorStringFormatter, com.datadog.android.sessionreplay.utils.ViewBoundsResolver, com.datadog.android.sessionreplay.utils.DrawableToColorMapper, com.datadog.android.sessionreplay.recorder.resources.DrawableCopier) override fun map(android.widget.ImageView, com.datadog.android.sessionreplay.recorder.MappingContext, com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback, com.datadog.android.api.InternalLogger): List open class com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper : BaseAsyncBackgroundWireframeMapper constructor(com.datadog.android.sessionreplay.utils.ViewIdentifierResolver, com.datadog.android.sessionreplay.utils.ColorStringFormatter, com.datadog.android.sessionreplay.utils.ViewBoundsResolver, com.datadog.android.sessionreplay.utils.DrawableToColorMapper) @@ -93,6 +93,10 @@ open class com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper : WireframeMapper interface com.datadog.android.sessionreplay.recorder.mapper.WireframeMapper fun map(T, com.datadog.android.sessionreplay.recorder.MappingContext, com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback, com.datadog.android.api.InternalLogger): List +class com.datadog.android.sessionreplay.recorder.resources.DefaultDrawableCopier : DrawableCopier + override fun copy(android.graphics.drawable.Drawable, android.content.res.Resources): android.graphics.drawable.Drawable? +interface com.datadog.android.sessionreplay.recorder.resources.DrawableCopier + fun copy(android.graphics.drawable.Drawable, android.content.res.Resources): android.graphics.drawable.Drawable? open class com.datadog.android.sessionreplay.utils.AndroidMDrawableToColorMapper : LegacyDrawableToColorMapper constructor(List = emptyList()) override fun resolveRippleDrawable(android.graphics.drawable.RippleDrawable, com.datadog.android.api.InternalLogger): Int? @@ -126,8 +130,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, String? = null): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe? - fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, AsyncJobStatusCallback): MutableList + fun createImageWireframeByDrawable(android.view.View, com.datadog.android.sessionreplay.ImagePrivacy, Int, Long, Long, Int, Int, Boolean, android.graphics.drawable.Drawable, com.datadog.android.sessionreplay.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? = null): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe? + fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, String?, AsyncJobStatusCallback): MutableList companion object open class com.datadog.android.sessionreplay.utils.LegacyDrawableToColorMapper : DrawableToColorMapper constructor(List = emptyList()) diff --git a/features/dd-sdk-android-session-replay/api/dd-sdk-android-session-replay.api b/features/dd-sdk-android-session-replay/api/dd-sdk-android-session-replay.api index 08d8e85f4b..cd5b8ca7e0 100644 --- a/features/dd-sdk-android-session-replay/api/dd-sdk-android-session-replay.api +++ b/features/dd-sdk-android-session-replay/api/dd-sdk-android-session-replay.api @@ -117,15 +117,6 @@ public final class com/datadog/android/sessionreplay/internal/recorder/obfuscato public final fun getStringObfuscator ()Lcom/datadog/android/sessionreplay/internal/recorder/obfuscator/StringObfuscator; } -public final class com/datadog/android/sessionreplay/internal/recorder/resources/DefaultDrawableCopier : com/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier { - public fun ()V - public fun copy (Landroid/graphics/drawable/Drawable;Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable; -} - -public abstract interface class com/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier { - public abstract fun copy (Landroid/graphics/drawable/Drawable;Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable; -} - public final class com/datadog/android/sessionreplay/model/MobileSegment { public static final field Companion Lcom/datadog/android/sessionreplay/model/MobileSegment$Companion; public fun (Lcom/datadog/android/sessionreplay/model/MobileSegment$Application;Lcom/datadog/android/sessionreplay/model/MobileSegment$Session;Lcom/datadog/android/sessionreplay/model/MobileSegment$View;JJJLjava/lang/Long;Ljava/lang/Boolean;Lcom/datadog/android/sessionreplay/model/MobileSegment$Source;Ljava/util/List;)V @@ -1453,7 +1444,11 @@ public final class com/datadog/android/sessionreplay/recorder/SystemInformation public abstract class com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper : com/datadog/android/sessionreplay/recorder/mapper/BaseWireframeMapper { public static final field Companion Lcom/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper$Companion; + public fun (Lcom/datadog/android/sessionreplay/utils/ViewIdentifierResolver;Lcom/datadog/android/sessionreplay/utils/ColorStringFormatter;Lcom/datadog/android/sessionreplay/utils/ViewBoundsResolver;Lcom/datadog/android/sessionreplay/utils/DrawableToColorMapper;)V public fun map (Landroid/view/View;Lcom/datadog/android/sessionreplay/recorder/MappingContext;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/api/InternalLogger;)Ljava/util/List; + protected fun resolveBackgroundAsImageWireframe (Landroid/view/View;Lcom/datadog/android/sessionreplay/utils/GlobalBounds;IILcom/datadog/android/sessionreplay/recorder/MappingContext;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe; + protected fun resolveBackgroundAsShapeWireframe (Landroid/view/View;Lcom/datadog/android/sessionreplay/utils/GlobalBounds;IILcom/datadog/android/sessionreplay/model/MobileSegment$ShapeStyle;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe$ShapeWireframe; + protected fun resolveViewBackground (Landroid/view/View;Lcom/datadog/android/sessionreplay/recorder/MappingContext;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/api/InternalLogger;)Lcom/datadog/android/sessionreplay/model/MobileSegment$Wireframe; } public final class com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper$Companion { @@ -1483,7 +1478,7 @@ public final class com/datadog/android/sessionreplay/recorder/mapper/EditTextMap } public class com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper : com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper { - public fun (Lcom/datadog/android/sessionreplay/utils/ViewIdentifierResolver;Lcom/datadog/android/sessionreplay/utils/ColorStringFormatter;Lcom/datadog/android/sessionreplay/utils/ViewBoundsResolver;Lcom/datadog/android/sessionreplay/utils/DrawableToColorMapper;)V + public fun (Lcom/datadog/android/sessionreplay/utils/ViewIdentifierResolver;Lcom/datadog/android/sessionreplay/utils/ColorStringFormatter;Lcom/datadog/android/sessionreplay/utils/ViewBoundsResolver;Lcom/datadog/android/sessionreplay/utils/DrawableToColorMapper;Lcom/datadog/android/sessionreplay/recorder/resources/DrawableCopier;)V public synthetic fun map (Landroid/view/View;Lcom/datadog/android/sessionreplay/recorder/MappingContext;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/api/InternalLogger;)Ljava/util/List; public fun map (Landroid/widget/ImageView;Lcom/datadog/android/sessionreplay/recorder/MappingContext;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/api/InternalLogger;)Ljava/util/List; } @@ -1503,6 +1498,15 @@ public abstract interface class com/datadog/android/sessionreplay/recorder/mappe public abstract fun map (Landroid/view/View;Lcom/datadog/android/sessionreplay/recorder/MappingContext;Lcom/datadog/android/sessionreplay/utils/AsyncJobStatusCallback;Lcom/datadog/android/api/InternalLogger;)Ljava/util/List; } +public final class com/datadog/android/sessionreplay/recorder/resources/DefaultDrawableCopier : com/datadog/android/sessionreplay/recorder/resources/DrawableCopier { + public fun ()V + public fun copy (Landroid/graphics/drawable/Drawable;Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable; +} + +public abstract interface class com/datadog/android/sessionreplay/recorder/resources/DrawableCopier { + public abstract fun copy (Landroid/graphics/drawable/Drawable;Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable; +} + public class com/datadog/android/sessionreplay/utils/AndroidMDrawableToColorMapper : com/datadog/android/sessionreplay/utils/LegacyDrawableToColorMapper { public fun ()V public fun (Ljava/util/List;)V @@ -1586,7 +1590,7 @@ public abstract interface class com/datadog/android/sessionreplay/utils/ImageWir 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;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;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/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 { @@ -1594,7 +1598,7 @@ public final class com/datadog/android/sessionreplay/utils/ImageWireframeHelper$ 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;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/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 { diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt index bbe80d462c..71f5243520 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt @@ -47,6 +47,7 @@ import com.datadog.android.sessionreplay.recorder.mapper.EditTextMapper import com.datadog.android.sessionreplay.recorder.mapper.ImageViewMapper import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper import com.datadog.android.sessionreplay.recorder.mapper.WireframeMapper +import com.datadog.android.sessionreplay.recorder.resources.DefaultDrawableCopier import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DefaultColorStringFormatter import com.datadog.android.sessionreplay.utils.DefaultViewBoundsResolver @@ -101,7 +102,8 @@ internal class DefaultRecorderProvider( colorStringFormatter = colorStringFormatter, viewBoundsResolver = viewBoundsResolver, drawableToColorMapper = drawableToColorMapper, - imageViewUtils = ImageViewUtils + imageViewUtils = ImageViewUtils, + drawableCopier = DefaultDrawableCopier() ) val textViewMapper = TextViewMapper( viewIdentifierResolver, diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt index ab75a3f988..3deedd746d 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt @@ -11,7 +11,7 @@ import android.widget.Checkable import android.widget.TextView import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt index 603ff000c1..c2b98d3b7b 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt @@ -10,7 +10,7 @@ import androidx.annotation.UiThread import androidx.appcompat.widget.SwitchCompat import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.internal.recorder.densityNormalized -import com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt index e915659362..ab27b6d6a6 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt @@ -20,6 +20,7 @@ import com.datadog.android.sessionreplay.internal.recorder.ViewUtilsInternal import com.datadog.android.sessionreplay.internal.recorder.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback import com.datadog.android.sessionreplay.utils.GlobalBounds import com.datadog.android.sessionreplay.utils.ImageWireframeHelper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolver.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolver.kt index de04810994..0ff79eaeb5 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolver.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolver.kt @@ -18,6 +18,7 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.core.internal.utils.executeSafe import com.datadog.android.sessionreplay.internal.async.DataQueueHandler import com.datadog.android.sessionreplay.internal.utils.DrawableUtils +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import java.util.concurrent.ExecutorService import java.util.concurrent.LinkedBlockingDeque import java.util.concurrent.ThreadPoolExecutor @@ -110,8 +111,8 @@ internal class ResourceResolver( // do in the background threadPoolExecutor.executeSafe("resolveResourceId", logger) { createBitmap( - resources = resources, drawable = originalDrawable, + copiedDrawable = copiedDrawable, drawableWidth = drawableWidth, drawableHeight = drawableHeight, displayMetrics = displayMetrics, @@ -137,8 +138,8 @@ internal class ResourceResolver( @WorkerThread private fun createBitmap( - resources: Resources, drawable: Drawable, + copiedDrawable: Drawable, drawableWidth: Int, drawableHeight: Int, displayMetrics: DisplayMetrics, @@ -148,7 +149,7 @@ internal class ResourceResolver( ) { val handledBitmap = if (bitmapFromDrawable != null) { tryToGetBitmapFromBitmapDrawable( - drawable = drawable as BitmapDrawable, + drawable = drawable, bitmapFromDrawable = bitmapFromDrawable, customResourceIdCacheKey = customResourceIdCacheKey, resolveResourceCallback = resolveResourceCallback @@ -159,8 +160,7 @@ internal class ResourceResolver( if (handledBitmap == null) { tryToDrawNewBitmap( - resources = resources, - drawable = drawable, + drawable = copiedDrawable, drawableWidth = drawableWidth, drawableHeight = drawableHeight, displayMetrics = displayMetrics, @@ -249,7 +249,6 @@ internal class ResourceResolver( @WorkerThread private fun tryToDrawNewBitmap( - resources: Resources, drawable: Drawable, drawableWidth: Int, drawableHeight: Int, @@ -258,7 +257,6 @@ internal class ResourceResolver( resolveResourceCallback: ResolveResourceCallback ) { drawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = resources, drawable = drawable, drawableWidth = drawableWidth, drawableHeight = drawableHeight, @@ -295,7 +293,7 @@ internal class ResourceResolver( @WorkerThread @Suppress("ReturnCount") private fun tryToGetBitmapFromBitmapDrawable( - drawable: BitmapDrawable, + drawable: Drawable, bitmapFromDrawable: Bitmap, customResourceIdCacheKey: String?, resolveResourceCallback: ResolveResourceCallback diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt index 49eebf59ea..6c531b3242 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt @@ -6,7 +6,6 @@ package com.datadog.android.sessionreplay.internal.utils -import android.content.res.Resources import android.graphics.Bitmap import android.graphics.Bitmap.Config import android.graphics.Color @@ -39,14 +38,13 @@ internal class DrawableUtils( */ @WorkerThread internal fun createBitmapOfApproxSizeFromDrawable( - resources: Resources, drawable: Drawable, drawableWidth: Int, drawableHeight: Int, displayMetrics: DisplayMetrics, requestedSizeInBytes: Int = MAX_BITMAP_SIZE_BYTES_WITH_RESOURCE_ENDPOINT, config: Config = Config.ARGB_8888, - bitmapCreationCallback: ResourceResolver.BitmapCreationCallback + bitmapCreationCallback: ResourceResolver.BitmapCreationCallback, ) { createScaledBitmap( drawableWidth, @@ -59,7 +57,6 @@ internal class DrawableUtils( override fun onSuccess(bitmap: Bitmap) { executorService.submitSafe("drawOnCanvas", internalLogger) { drawOnCanvas( - resources, bitmap, drawable, bitmapCreationCallback @@ -103,27 +100,26 @@ internal class DrawableUtils( @WorkerThread private fun drawOnCanvas( - resources: Resources, bitmap: Bitmap, drawable: Drawable, bitmapCreationCallback: ResourceResolver.BitmapCreationCallback ) { - // don't use the original drawable - it will affect the view hierarchy - val newDrawable = drawable.constantState?.newDrawable(resources)?.apply { - // `constantState` contains only immutable properties of drawable,the state needs to be set manually - setState(drawable.current.state) - } + // PR NOTE: + // The logic to create a copy of the drawable was removed. + // We should verify that it is safe not to copy the drawable. + // Currently, this function seems to be used only with drawables that were already cloned. + val canvas = canvasWrapper.createCanvas(bitmap) - if (canvas == null || newDrawable == null) { + if (canvas == null) { bitmapCreationCallback.onFailure() } else { // erase the canvas // needed because overdrawing an already used bitmap causes unusual visual artifacts canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY) - newDrawable.setBounds(0, 0, canvas.width, canvas.height) - newDrawable.draw(canvas) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) bitmapCreationCallback.onReady(bitmap) } } diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt index e3f4cad38a..6b1182a1df 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt @@ -31,7 +31,7 @@ import com.datadog.android.sessionreplay.utils.ViewIdentifierResolver * @param viewBoundsResolver the [ViewBoundsResolver] to get a view boundaries in density independent units * @param drawableToColorMapper the [DrawableToColorMapper] to convert a background drawable into a solid color */ -abstract class BaseAsyncBackgroundWireframeMapper internal constructor( +abstract class BaseAsyncBackgroundWireframeMapper ( viewIdentifierResolver: ViewIdentifierResolver, colorStringFormatter: ColorStringFormatter, viewBoundsResolver: ViewBoundsResolver, @@ -57,8 +57,16 @@ abstract class BaseAsyncBackgroundWireframeMapper internal construc return backgroundWireframe?.let { listOf(it) } ?: emptyList() } + /** + * Function used to resolve the Wireframe to represent the view background, based on its type. + * + * @param view the [View] to map + * @param mappingContext the [MappingContext] which contains contextual data, useful for mapping. + * @param asyncJobStatusCallback the [AsyncJobStatusCallback] callback used for internal async operations. + * @param internalLogger the [InternalLogger], used for internal logging. + */ @UiThread - private fun resolveViewBackground( + protected open fun resolveViewBackground( view: View, mappingContext: MappingContext, asyncJobStatusCallback: AsyncJobStatusCallback, @@ -90,7 +98,16 @@ abstract class BaseAsyncBackgroundWireframeMapper internal construc } } - private fun resolveBackgroundAsShapeWireframe( + /** + * Function used to resolve the view background as a Shape wireframe. + * + * @param view the [View] to map + * @param bounds the [GlobalBounds] of the view. + * @param width the view width. + * @param height the view height. + * @param shapeStyle the optional [MobileSegment.ShapeStyle] to use. + */ + protected open fun resolveBackgroundAsShapeWireframe( view: View, bounds: GlobalBounds, width: Int, @@ -115,8 +132,18 @@ abstract class BaseAsyncBackgroundWireframeMapper internal construc ) } + /** + * Function used to resolve the view background as a Image wireframe. + * + * @param view the [View] to map + * @param bounds the [GlobalBounds] of the view. + * @param width the view width. + * @param height the view height. + * @param mappingContext the [MappingContext] which contains contextual data, useful for mapping. + * @param asyncJobStatusCallback the [AsyncJobStatusCallback] callback used for internal async operations. + */ @UiThread - private fun resolveBackgroundAsImageWireframe( + protected open fun resolveBackgroundAsImageWireframe( view: View, bounds: GlobalBounds, width: Int, diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt index 4d5b9a16c1..43165c29ea 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt @@ -13,6 +13,7 @@ import com.datadog.android.sessionreplay.internal.recorder.densityNormalized import com.datadog.android.sessionreplay.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DrawableToColorMapper @@ -25,19 +26,22 @@ import com.datadog.android.sessionreplay.utils.ViewIdentifierResolver */ open class ImageViewMapper : BaseAsyncBackgroundWireframeMapper { private val imageViewUtils: ImageViewUtils + private val drawableCopier: DrawableCopier @Suppress("Unused") // used by external mappers constructor( viewIdentifierResolver: ViewIdentifierResolver, colorStringFormatter: ColorStringFormatter, viewBoundsResolver: ViewBoundsResolver, - drawableToColorMapper: DrawableToColorMapper + drawableToColorMapper: DrawableToColorMapper, + drawableCopier: DrawableCopier ) : this( viewIdentifierResolver, colorStringFormatter, viewBoundsResolver, drawableToColorMapper, - ImageViewUtils + ImageViewUtils, + drawableCopier ) internal constructor( @@ -45,14 +49,16 @@ open class ImageViewMapper : BaseAsyncBackgroundWireframeMapper { colorStringFormatter: ColorStringFormatter, viewBoundsResolver: ViewBoundsResolver, drawableToColorMapper: DrawableToColorMapper, - imageViewUtils: ImageViewUtils + imageViewUtils: ImageViewUtils, + drawableCopier: DrawableCopier ) : super( viewIdentifierResolver, colorStringFormatter, viewBoundsResolver, - drawableToColorMapper + drawableToColorMapper, ) { this.imageViewUtils = imageViewUtils + this.drawableCopier = drawableCopier } @UiThread @@ -97,6 +103,7 @@ open class ImageViewMapper : BaseAsyncBackgroundWireframeMapper { height = contentHeightPx, usePIIPlaceholder = true, drawable = drawable, + drawableCopier = drawableCopier, asyncJobStatusCallback = asyncJobStatusCallback, clipping = clipping, shapeStyle = null, diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultDrawableCopier.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/resources/DefaultDrawableCopier.kt similarity index 83% rename from features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultDrawableCopier.kt rename to features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/resources/DefaultDrawableCopier.kt index 8bd17fdba1..92f527d404 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultDrawableCopier.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/resources/DefaultDrawableCopier.kt @@ -4,16 +4,14 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.sessionreplay.internal.recorder.resources +package com.datadog.android.sessionreplay.recorder.resources import android.content.res.Resources import android.graphics.drawable.Drawable -import com.datadog.android.lint.InternalApi /** * Default implementation of [DrawableCopier] interface, it copies the drawable from constant state. */ -@InternalApi class DefaultDrawableCopier : DrawableCopier { override fun copy(originalDrawable: Drawable, resources: Resources): Drawable? { return originalDrawable.constantState?.newDrawable(resources) diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/resources/DrawableCopier.kt similarity index 84% rename from features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier.kt rename to features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/resources/DrawableCopier.kt index f732b1b5a4..a01e0bc09f 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/resources/DrawableCopier.kt @@ -4,16 +4,14 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.sessionreplay.internal.recorder.resources +package com.datadog.android.sessionreplay.recorder.resources import android.content.res.Resources import android.graphics.drawable.Drawable -import com.datadog.android.lint.InternalApi /** * Interface of copying drawable to a new one. */ -@InternalApi fun interface DrawableCopier { /** diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt index b147caf4ce..b1c258beb8 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt @@ -12,8 +12,8 @@ import android.view.View import android.widget.TextView import androidx.annotation.UiThread import com.datadog.android.sessionreplay.ImagePrivacy -import com.datadog.android.sessionreplay.internal.recorder.resources.DefaultDrawableCopier -import com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier +import com.datadog.android.sessionreplay.recorder.resources.DefaultDrawableCopier +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt index 930c1a030f..e3b0246422 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt @@ -17,7 +17,7 @@ import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.sessionreplay.internal.recorder.mapper.CheckableTextViewMapper.Companion.CHECK_BOX_CHECKED_DRAWABLE_INDEX import com.datadog.android.sessionreplay.internal.recorder.mapper.CheckableTextViewMapper.Companion.CHECK_BOX_NOT_CHECKED_DRAWABLE_INDEX -import com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper import com.datadog.android.sessionreplay.utils.GlobalBounds diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolverTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolverTest.kt index 7f8b40bec7..8d640190d3 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolverTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ResourceResolverTest.kt @@ -18,6 +18,7 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.sessionreplay.internal.async.RecordedDataQueueHandler import com.datadog.android.sessionreplay.internal.utils.DrawableUtils +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.StringForgery @@ -141,7 +142,6 @@ internal class ResourceResolverTest { whenever( mockDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -151,7 +151,7 @@ internal class ResourceResolverTest { bitmapCreationCallback = any() ) ).then { - (it.arguments[7] as ResourceResolver.BitmapCreationCallback).onReady(mockBitmap) + (it.arguments[6] as ResourceResolver.BitmapCreationCallback).onReady(mockBitmap) } // executeSafe is an extension so we have to mock the internal execute function @@ -233,7 +233,6 @@ internal class ResourceResolverTest { // Then verify(mockDrawableUtils).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -342,7 +341,6 @@ internal class ResourceResolverTest { // Then verify(mockDrawableUtils).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -359,7 +357,6 @@ internal class ResourceResolverTest { whenever(mockResourcesLRUCache.get(fakeResourceKey)).thenReturn(null) whenever( mockDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -369,7 +366,7 @@ internal class ResourceResolverTest { bitmapCreationCallback = any() ) ).then { - (it.arguments[7] as ResourceResolver.BitmapCreationCallback).onFailure() + (it.arguments[6] as ResourceResolver.BitmapCreationCallback).onFailure() } // When @@ -459,7 +456,6 @@ internal class ResourceResolverTest { // Then verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -490,7 +486,6 @@ internal class ResourceResolverTest { // Then verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -547,7 +542,6 @@ internal class ResourceResolverTest { anyOrNull() ) verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -582,7 +576,6 @@ internal class ResourceResolverTest { anyOrNull() ) verify(mockDrawableUtils, times(1)).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), @@ -873,7 +866,6 @@ internal class ResourceResolverTest { // Then verify(mockDrawableUtils).createBitmapOfApproxSizeFromDrawable( - resources = any(), drawable = any(), drawableWidth = any(), drawableHeight = any(), diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt index e46f22922d..8db0db8bb4 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt @@ -141,7 +141,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -179,7 +178,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -214,7 +212,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -254,7 +251,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -279,7 +275,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -297,12 +292,13 @@ internal class DrawableUtilsTest { // Given whenever(mockDrawable.intrinsicWidth).thenReturn(1) whenever(mockDrawable.intrinsicHeight).thenReturn(1) - whenever(mockConstantState.newDrawable(mockResources)) - .thenReturn(null) + whenever(mockBitmap.isRecycled).thenReturn(true) + whenever(mockBitmapWrapper.createBitmap(any(), any(), any(), any())).thenReturn( + null + ) // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -325,7 +321,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -353,7 +348,6 @@ internal class DrawableUtilsTest { // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -379,14 +373,19 @@ internal class DrawableUtilsTest { } @Test - fun `M not use original drawable W createBitmapOfApproxSizeFromDrawable`() { + fun `M uses original drawable W createBitmapOfApproxSizeFromDrawable`() { + /** + * PR NOTE: + * - This PR changes the logic so that createBitmapOfApproxSizeFromDrawable -> drawOnCanvas does not + * create a copy of the original drawable. We should confirm that this is OK. + **/ + // Given whenever(mockDrawable.intrinsicWidth).thenReturn(1) whenever(mockDrawable.intrinsicHeight).thenReturn(1) // When testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - resources = mockResources, drawable = mockDrawable, drawableWidth = mockDrawable.intrinsicWidth, drawableHeight = mockDrawable.intrinsicHeight, @@ -396,10 +395,10 @@ internal class DrawableUtilsTest { ) // Then - verify(mockDrawable, never()).setBounds(any(), any(), any(), any()) - verify(mockDrawable, never()).draw(any()) - verify(mockSecondDrawable).setBounds(any(), any(), any(), any()) - verify(mockSecondDrawable).draw(any()) + verify(mockDrawable).setBounds(any(), any(), any(), any()) + verify(mockDrawable).draw(any()) + verify(mockSecondDrawable, never()).setBounds(any(), any(), any(), any()) + verify(mockSecondDrawable, never()).draw(any()) } @Test diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt index 9bf84246ba..ae0faebb7f 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt @@ -22,6 +22,7 @@ import com.datadog.android.sessionreplay.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.SystemInformation +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DrawableToColorMapper @@ -100,6 +101,9 @@ internal class ImageViewMapperTest { @Mock lateinit var mockDrawableToColorMapper: DrawableToColorMapper + @Mock + lateinit var mockDrawableCopier: DrawableCopier + @Mock lateinit var mockGlobalBounds: GlobalBounds @@ -197,7 +201,8 @@ internal class ImageViewMapperTest { colorStringFormatter = mockColorStringFormatter, viewBoundsResolver = mockViewBoundsResolver, drawableToColorMapper = mockDrawableToColorMapper, - imageViewUtils = stubImageViewUtils + imageViewUtils = stubImageViewUtils, + drawableCopier = mockDrawableCopier ) } From bf75df990bb3fbeb70afcbea66dae0126fc993d7 Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Fri, 6 Dec 2024 12:44:52 +0100 Subject: [PATCH 3/9] Format changes with ktlint --- .../internal/recorder/mapper/CheckableTextViewMapper.kt | 2 +- .../internal/recorder/mapper/SwitchCompatMapper.kt | 2 +- .../android/sessionreplay/internal/utils/DrawableUtils.kt | 2 +- .../android/sessionreplay/recorder/mapper/ImageViewMapper.kt | 2 +- .../android/sessionreplay/utils/ImageWireframeHelper.kt | 4 ++-- .../recorder/mapper/BaseCheckableTextViewMapperTest.kt | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt index 3deedd746d..c4fb1f894b 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt @@ -11,10 +11,10 @@ import android.widget.Checkable import android.widget.TextView import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DrawableToColorMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt index c2b98d3b7b..f63afa1c3f 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt @@ -10,10 +10,10 @@ import androidx.annotation.UiThread import androidx.appcompat.widget.SwitchCompat import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.internal.recorder.densityNormalized -import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DrawableToColorMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt index 6c531b3242..23789d66a4 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt @@ -44,7 +44,7 @@ internal class DrawableUtils( displayMetrics: DisplayMetrics, requestedSizeInBytes: Int = MAX_BITMAP_SIZE_BYTES_WITH_RESOURCE_ENDPOINT, config: Config = Config.ARGB_8888, - bitmapCreationCallback: ResourceResolver.BitmapCreationCallback, + bitmapCreationCallback: ResourceResolver.BitmapCreationCallback ) { createScaledBitmap( drawableWidth, diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt index 43165c29ea..93fbf98541 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt @@ -55,7 +55,7 @@ open class ImageViewMapper : BaseAsyncBackgroundWireframeMapper { viewIdentifierResolver, colorStringFormatter, viewBoundsResolver, - drawableToColorMapper, + drawableToColorMapper ) { this.imageViewUtils = imageViewUtils this.drawableCopier = drawableCopier diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt index b1c258beb8..d627d49fe0 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/utils/ImageWireframeHelper.kt @@ -12,10 +12,10 @@ import android.view.View import android.widget.TextView import androidx.annotation.UiThread import com.datadog.android.sessionreplay.ImagePrivacy -import com.datadog.android.sessionreplay.recorder.resources.DefaultDrawableCopier -import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext +import com.datadog.android.sessionreplay.recorder.resources.DefaultDrawableCopier +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier /** * A Helper to handle capturing images in Session replay wireframes. diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt index e3b0246422..15558911ff 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt @@ -17,9 +17,9 @@ import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.sessionreplay.internal.recorder.mapper.CheckableTextViewMapper.Companion.CHECK_BOX_CHECKED_DRAWABLE_INDEX import com.datadog.android.sessionreplay.internal.recorder.mapper.CheckableTextViewMapper.Companion.CHECK_BOX_NOT_CHECKED_DRAWABLE_INDEX -import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper +import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier import com.datadog.android.sessionreplay.utils.GlobalBounds import com.datadog.android.sessionreplay.utils.OPAQUE_ALPHA_VALUE import com.datadog.tools.unit.annotations.TestTargetApi From 881456ab2a2cbaf9e5fe5ba1c62aafe78e1e1d8c Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Mon, 9 Dec 2024 16:04:55 +0100 Subject: [PATCH 4/9] Updated apiSurface --- features/dd-sdk-android-session-replay/api/apiSurface | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/dd-sdk-android-session-replay/api/apiSurface b/features/dd-sdk-android-session-replay/api/apiSurface index a9cf3af341..ad23691fd8 100644 --- a/features/dd-sdk-android-session-replay/api/apiSurface +++ b/features/dd-sdk-android-session-replay/api/apiSurface @@ -130,7 +130,7 @@ 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.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? = 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.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 companion object open class com.datadog.android.sessionreplay.utils.LegacyDrawableToColorMapper : DrawableToColorMapper From ff3fb614f511683a15db9b18caf19c1ad124d2b3 Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Tue, 10 Dec 2024 10:56:33 +0100 Subject: [PATCH 5/9] Removed PR notes --- .../android/sessionreplay/internal/utils/DrawableUtils.kt | 5 ----- .../sessionreplay/internal/utils/DrawableUtilsTest.kt | 6 ------ 2 files changed, 11 deletions(-) diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt index 23789d66a4..1e6dadf165 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtils.kt @@ -104,11 +104,6 @@ internal class DrawableUtils( drawable: Drawable, bitmapCreationCallback: ResourceResolver.BitmapCreationCallback ) { - // PR NOTE: - // The logic to create a copy of the drawable was removed. - // We should verify that it is safe not to copy the drawable. - // Currently, this function seems to be used only with drawables that were already cloned. - val canvas = canvasWrapper.createCanvas(bitmap) if (canvas == null) { diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt index 8db0db8bb4..fb072896d3 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt @@ -374,12 +374,6 @@ internal class DrawableUtilsTest { @Test fun `M uses original drawable W createBitmapOfApproxSizeFromDrawable`() { - /** - * PR NOTE: - * - This PR changes the logic so that createBitmapOfApproxSizeFromDrawable -> drawOnCanvas does not - * create a copy of the original drawable. We should confirm that this is OK. - **/ - // Given whenever(mockDrawable.intrinsicWidth).thenReturn(1) whenever(mockDrawable.intrinsicHeight).thenReturn(1) From cccfa94b6f233b9078c727a40e93559f410b0c19 Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Tue, 10 Dec 2024 11:57:57 +0100 Subject: [PATCH 6/9] Moved ImageView and density utils to dd-sdk-android-internal --- dd-sdk-android-internal/api/apiSurface | 6 +++++ .../api/dd-sdk-android-internal.api | 15 ++++++++++++ .../android}/internal/utils/ImageViewUtils.kt | 23 ++++++++----------- .../datadog/android/internal/utils}/IntExt.kt | 4 ++-- .../android/internal/utils}/LongExt.kt | 4 ++-- .../internal/DefaultRecorderProvider.kt | 2 +- .../internal/recorder/ViewUtilsInternal.kt | 1 + .../callback/RecorderWindowCallback.kt | 2 +- .../recorder/mapper/BasePickerMapper.kt | 2 +- .../mapper/CheckableCompoundButtonMapper.kt | 2 +- .../recorder/mapper/CheckedTextViewMapper.kt | 2 +- .../mapper/ProgressBarWireframeMapper.kt | 2 +- .../recorder/mapper/SeekBarWireframeMapper.kt | 2 +- .../recorder/mapper/SwitchCompatMapper.kt | 2 +- .../resources/DefaultImageWireframeHelper.kt | 2 +- .../recorder/resources/ImageTypeResolver.kt | 2 +- .../sessionreplay/internal/utils/MiscUtils.kt | 2 +- .../sessionreplay/internal/utils/RectExt.kt | 19 +++++++++++++++ .../BaseAsyncBackgroundWireframeMapper.kt | 2 +- .../recorder/mapper/ImageViewMapper.kt | 8 ++++--- .../recorder/mapper/TextViewMapper.kt | 2 +- .../internal/recorder/IntExtTest.kt | 1 + .../internal/recorder/LongExtTest.kt | 1 + .../mapper/BaseNumberPickerMapperTest.kt | 2 +- .../mapper/BaseSwitchCompatMapperTest.kt | 2 +- .../mapper/ProgressBarWireframeMapperTest.kt | 2 +- .../mapper/SeekBarWireframeMapperTest.kt | 2 +- .../recorder/mapper/SwitchCompatMapperTest.kt | 2 +- .../internal/utils/ImageViewUtilsTest.kt | 11 +++++---- .../internal/utils/MiscUtilsTest.kt | 2 +- .../recorder/mapper/ImageViewMapperTest.kt | 4 ++-- .../utils/DefaultViewBoundsResolverTest.kt | 2 +- 32 files changed, 90 insertions(+), 47 deletions(-) rename {features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay => dd-sdk-android-internal/src/main/java/com/datadog/android}/internal/utils/ImageViewUtils.kt (90%) rename {features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder => dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils}/IntExt.kt (83%) rename {features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder => dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils}/LongExt.kt (83%) create mode 100644 features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt diff --git a/dd-sdk-android-internal/api/apiSurface b/dd-sdk-android-internal/api/apiSurface index f80629999a..597d40934f 100644 --- a/dd-sdk-android-internal/api/apiSurface +++ b/dd-sdk-android-internal/api/apiSurface @@ -29,6 +29,12 @@ sealed class com.datadog.android.internal.telemetry.InternalTelemetryEvent constructor(Boolean, Boolean, Boolean, MutableMap = mutableMapOf()) object InterceptorInstantiated : InternalTelemetryEvent fun ByteArray.toHexString(): String +object com.datadog.android.internal.utils.ImageViewUtils + fun resolveParentRectAbsPosition(android.view.View): android.graphics.Rect + fun calculateClipping(android.graphics.Rect, android.graphics.Rect, Float): android.graphics.Rect + fun resolveContentRectWithScaling(android.widget.ImageView, android.graphics.drawable.Drawable): android.graphics.Rect +fun Int.densityNormalized(Float): Int +fun Long.densityNormalized(Float): Long fun Throwable.loggableStackTrace(): String annotation com.datadog.tools.annotation.NoOpImplementation constructor(Boolean = false) diff --git a/dd-sdk-android-internal/api/dd-sdk-android-internal.api b/dd-sdk-android-internal/api/dd-sdk-android-internal.api index a6ae5b9963..f15b234506 100644 --- a/dd-sdk-android-internal/api/dd-sdk-android-internal.api +++ b/dd-sdk-android-internal/api/dd-sdk-android-internal.api @@ -108,6 +108,21 @@ public final class com/datadog/android/internal/utils/ByteArrayExtKt { public static final fun toHexString ([B)Ljava/lang/String; } +public final class com/datadog/android/internal/utils/ImageViewUtils { + public static final field INSTANCE Lcom/datadog/android/internal/utils/ImageViewUtils; + public final fun calculateClipping (Landroid/graphics/Rect;Landroid/graphics/Rect;F)Landroid/graphics/Rect; + public final fun resolveContentRectWithScaling (Landroid/widget/ImageView;Landroid/graphics/drawable/Drawable;)Landroid/graphics/Rect; + public final fun resolveParentRectAbsPosition (Landroid/view/View;)Landroid/graphics/Rect; +} + +public final class com/datadog/android/internal/utils/IntExtKt { + public static final fun densityNormalized (IF)I +} + +public final class com/datadog/android/internal/utils/LongExtKt { + public static final fun densityNormalized (JF)J +} + public final class com/datadog/android/internal/utils/ThrowableExtKt { public static final fun loggableStackTrace (Ljava/lang/Throwable;)Ljava/lang/String; } diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtils.kt b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt similarity index 90% rename from features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtils.kt rename to dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt index d5ca9d6b26..589e065f8d 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtils.kt +++ b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt @@ -4,17 +4,15 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.sessionreplay.internal.utils +package com.datadog.android.internal.utils import android.graphics.Rect import android.graphics.drawable.Drawable import android.view.View import android.widget.ImageView -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized -import com.datadog.android.sessionreplay.model.MobileSegment -internal object ImageViewUtils { - internal fun resolveParentRectAbsPosition(view: View): Rect { +object ImageViewUtils { + fun resolveParentRectAbsPosition(view: View): Rect { val coords = IntArray(2) // this will always have size >= 2 @Suppress("UnsafeThirdPartyFunctionCall") @@ -31,7 +29,7 @@ internal object ImageViewUtils { ) } - internal fun calculateClipping(parentRect: Rect, childRect: Rect, density: Float): MobileSegment.WireframeClip { + fun calculateClipping(parentRect: Rect, childRect: Rect, density: Float): Rect { val left = if (childRect.left < parentRect.left) { parentRect.left - childRect.left } else { @@ -52,16 +50,15 @@ internal object ImageViewUtils { } else { 0 } - - return MobileSegment.WireframeClip( - left = left.densityNormalized(density).toLong(), - top = top.densityNormalized(density).toLong(), - right = right.densityNormalized(density).toLong(), - bottom = bottom.densityNormalized(density).toLong() + return Rect( + left.densityNormalized(density), + top.densityNormalized(density), + right.densityNormalized(density), + bottom.densityNormalized(density) ) } - internal fun resolveContentRectWithScaling( + fun resolveContentRectWithScaling( imageView: ImageView, drawable: Drawable ): Rect { diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExt.kt b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/IntExt.kt similarity index 83% rename from features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExt.kt rename to dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/IntExt.kt index 59d515a40e..04d5528f34 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExt.kt +++ b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/IntExt.kt @@ -4,7 +4,7 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.sessionreplay.internal.recorder +package com.datadog.android.internal.utils /** * Normalizes an Int value (font size, view dimension, view position, etc.) according with the @@ -13,7 +13,7 @@ package com.datadog.android.sessionreplay.internal.recorder * view.height/2. * @param density */ -internal fun Int.densityNormalized(density: Float): Int { +fun Int.densityNormalized(density: Float): Int { if (density == 0f) { return this } diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExt.kt b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/LongExt.kt similarity index 83% rename from features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExt.kt rename to dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/LongExt.kt index 53e04d322e..b057e92220 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExt.kt +++ b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/LongExt.kt @@ -4,7 +4,7 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.sessionreplay.internal.recorder +package com.datadog.android.internal.utils /** * Normalizes a Long value (font size, view dimension, view position, etc.) according with the @@ -13,7 +13,7 @@ package com.datadog.android.sessionreplay.internal.recorder * view.height/2. * @param density */ -internal fun Long.densityNormalized(density: Float): Long { +fun Long.densityNormalized(density: Float): Long { if (density == 0f) { return this } diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt index 71f5243520..a2eaa226b1 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt @@ -41,7 +41,7 @@ import com.datadog.android.sessionreplay.internal.resources.ResourceDataStoreMan import com.datadog.android.sessionreplay.internal.storage.RecordWriter import com.datadog.android.sessionreplay.internal.storage.ResourcesWriter import com.datadog.android.sessionreplay.internal.time.SessionReplayTimeProvider -import com.datadog.android.sessionreplay.internal.utils.ImageViewUtils +import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.recorder.OptionSelectorDetector import com.datadog.android.sessionreplay.recorder.mapper.EditTextMapper import com.datadog.android.sessionreplay.recorder.mapper.ImageViewMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/ViewUtilsInternal.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/ViewUtilsInternal.kt index 41bca26faa..dd9f119ab0 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/ViewUtilsInternal.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/ViewUtilsInternal.kt @@ -12,6 +12,7 @@ import android.view.View import android.view.ViewStub import androidx.appcompat.widget.ActionBarContextView import androidx.appcompat.widget.Toolbar +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.recorder.resources.DefaultImageWireframeHelper import com.datadog.android.sessionreplay.utils.GlobalBounds diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt index 40293a5ae4..bca8604426 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt @@ -18,7 +18,7 @@ import com.datadog.android.sessionreplay.internal.TouchPrivacyManager import com.datadog.android.sessionreplay.internal.async.RecordedDataQueueHandler import com.datadog.android.sessionreplay.internal.recorder.ViewOnDrawInterceptor import com.datadog.android.sessionreplay.internal.recorder.WindowInspector -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.utils.TimeProvider import com.datadog.android.sessionreplay.model.MobileSegment import java.util.LinkedList diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BasePickerMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BasePickerMapper.kt index 712a2b6dfd..7031d33ea7 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BasePickerMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BasePickerMapper.kt @@ -9,7 +9,7 @@ package com.datadog.android.sessionreplay.internal.recorder.mapper import android.os.Build import android.widget.NumberPicker import androidx.annotation.RequiresApi -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.BaseWireframeMapper import com.datadog.android.sessionreplay.utils.ColorStringFormatter diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableCompoundButtonMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableCompoundButtonMapper.kt index 1d057ff9a9..8cc7d1f449 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableCompoundButtonMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableCompoundButtonMapper.kt @@ -12,7 +12,7 @@ import android.os.Build import android.widget.CompoundButton import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DrawableToColorMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckedTextViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckedTextViewMapper.kt index 05222776c7..9b788120bc 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckedTextViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckedTextViewMapper.kt @@ -10,7 +10,7 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.DrawableContainer import android.widget.CheckedTextView import androidx.annotation.UiThread -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper import com.datadog.android.sessionreplay.utils.ColorStringFormatter import com.datadog.android.sessionreplay.utils.DrawableToColorMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt index 621cc5e6fb..d72c27771a 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt @@ -15,7 +15,7 @@ import androidx.annotation.RequiresApi import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.TextAndInputPrivacy -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.BaseAsyncBackgroundWireframeMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt index c2cd516288..5b550a91d5 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt @@ -9,7 +9,7 @@ package com.datadog.android.sessionreplay.internal.recorder.mapper import android.widget.SeekBar import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.TextAndInputPrivacy -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt index f63afa1c3f..c25c7ce16d 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt @@ -9,7 +9,7 @@ package com.datadog.android.sessionreplay.internal.recorder.mapper import androidx.annotation.UiThread import androidx.appcompat.widget.SwitchCompat import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt index ab27b6d6a6..27e7e7c8ea 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt @@ -17,7 +17,7 @@ import androidx.annotation.VisibleForTesting import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.internal.recorder.ViewUtilsInternal -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ImageTypeResolver.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ImageTypeResolver.kt index a414a0849b..4417eb3927 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ImageTypeResolver.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/ImageTypeResolver.kt @@ -9,7 +9,7 @@ package com.datadog.android.sessionreplay.internal.recorder.resources import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import androidx.annotation.VisibleForTesting -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized internal class ImageTypeResolver { fun isDrawablePII(drawable: Drawable, density: Float): Boolean { diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtils.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtils.kt index 96a7859abb..324d7db542 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtils.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtils.kt @@ -13,7 +13,7 @@ import android.os.Build import android.util.TypedValue import android.view.WindowManager import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.recorder.SystemInformation import com.datadog.android.sessionreplay.utils.DefaultColorStringFormatter import com.datadog.android.sessionreplay.utils.GlobalBounds diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt new file mode 100644 index 0000000000..f67ffd8edd --- /dev/null +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt @@ -0,0 +1,19 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.android.sessionreplay.internal.utils + +import android.graphics.Rect +import com.datadog.android.sessionreplay.model.MobileSegment + +internal fun Rect.toWireframeClip(): MobileSegment.WireframeClip { + return MobileSegment.WireframeClip( + this.top.toLong(), + this.bottom.toLong(), + this.left.toLong(), + this.right.toLong() + ) +} \ No newline at end of file diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt index 6b1182a1df..7d64174f59 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/BaseAsyncBackgroundWireframeMapper.kt @@ -9,7 +9,7 @@ package com.datadog.android.sessionreplay.recorder.mapper import android.view.View import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt index 93fbf98541..63f3cd82f5 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt @@ -9,8 +9,10 @@ package com.datadog.android.sessionreplay.recorder.mapper import android.widget.ImageView import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized -import com.datadog.android.sessionreplay.internal.utils.ImageViewUtils +import com.datadog.android.internal.utils.ImageViewUtils +import com.datadog.android.internal.utils.densityNormalized +import com.datadog.android.sessionreplay.SessionReplay +import com.datadog.android.sessionreplay.internal.utils.toWireframeClip import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier @@ -82,7 +84,7 @@ open class ImageViewMapper : BaseAsyncBackgroundWireframeMapper { val density = resources.displayMetrics.density val clipping = if (view.cropToPadding) { - imageViewUtils.calculateClipping(parentRect, contentRect, density) + imageViewUtils.calculateClipping(parentRect, contentRect, density).toWireframeClip() } else { null } diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt index 85ba1b627b..d0b6d8d27a 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt @@ -12,7 +12,7 @@ import android.widget.TextView import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.TextAndInputPrivacy -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.recorder.obfuscator.StringObfuscator import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExtTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExtTest.kt index 68a9b90fc4..cc4da5de0e 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExtTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/IntExtTest.kt @@ -6,6 +6,7 @@ package com.datadog.android.sessionreplay.internal.recorder +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.forge.ForgeConfigurator import fr.xgouchet.elmyr.annotation.FloatForgery import fr.xgouchet.elmyr.annotation.IntForgery diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExtTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExtTest.kt index 0715d2f8b1..be1842864d 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExtTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/LongExtTest.kt @@ -6,6 +6,7 @@ package com.datadog.android.sessionreplay.internal.recorder +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.forge.ForgeConfigurator import fr.xgouchet.elmyr.annotation.FloatForgery import fr.xgouchet.elmyr.annotation.LongForgery diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseNumberPickerMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseNumberPickerMapperTest.kt index 67b0596bb0..e74dcfbd27 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseNumberPickerMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseNumberPickerMapperTest.kt @@ -7,7 +7,7 @@ package com.datadog.android.sessionreplay.internal.recorder.mapper import android.widget.NumberPicker -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.utils.GlobalBounds import com.datadog.android.sessionreplay.utils.OPAQUE_ALPHA_VALUE diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt index c48948df15..f2e053a3c1 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt @@ -13,7 +13,7 @@ import android.graphics.drawable.Drawable.ConstantState import androidx.appcompat.widget.SwitchCompat import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper import com.datadog.android.sessionreplay.utils.GlobalBounds diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt index ed4e4dfcb4..26f09c0188 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt @@ -6,7 +6,7 @@ import android.os.Build import android.widget.ProgressBar import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.recorder.mapper.SeekBarWireframeMapper.Companion.TRACK_HEIGHT_IN_PX import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.AbstractWireframeMapperTest diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt index a282d78e9f..cb59ba0627 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt @@ -7,7 +7,7 @@ import android.os.Build import android.widget.SeekBar import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.recorder.mapper.SeekBarWireframeMapper.Companion.TRACK_HEIGHT_IN_PX import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.AbstractWireframeMapperTest diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt index ccb3181a0d..8d7c146332 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt @@ -10,7 +10,7 @@ import android.graphics.drawable.Drawable import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeConfiguration diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtilsTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtilsTest.kt index 45bf0adcdd..b3ad5c0df4 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtilsTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/ImageViewUtilsTest.kt @@ -10,6 +10,7 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.view.View import android.widget.ImageView +import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.utils.isCloseToOrGreaterThan @@ -72,7 +73,7 @@ internal class ImageViewUtilsTest { ) // Then - assertThat(result).isEqualTo(expectedClipping) + assertThat(result.toWireframeClip()).isEqualTo(expectedClipping) } @Test @@ -104,7 +105,7 @@ internal class ImageViewUtilsTest { ) // Then - assertThat(result).isEqualTo(expectedClipping) + assertThat(result.toWireframeClip()).isEqualTo(expectedClipping) } @Test @@ -136,7 +137,7 @@ internal class ImageViewUtilsTest { ) // Then - assertThat(result).isEqualTo(expectedClipping) + assertThat(result.toWireframeClip()).isEqualTo(expectedClipping) } @Test @@ -168,7 +169,7 @@ internal class ImageViewUtilsTest { ) // Then - assertThat(result).isEqualTo(expectedClipping) + assertThat(result.toWireframeClip()).isEqualTo(expectedClipping) } @Test @@ -200,7 +201,7 @@ internal class ImageViewUtilsTest { ) // Then - assertThat(result).isEqualTo(expectedClipping) + assertThat(result.toWireframeClip()).isEqualTo(expectedClipping) } // endregion diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt index 12187927b2..94a2d91c29 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt @@ -20,7 +20,7 @@ import android.view.WindowManager import android.view.WindowMetrics import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.utils.MiscUtils.DESERIALIZE_JSON_ERROR import com.datadog.android.sessionreplay.recorder.SystemInformation import com.datadog.android.sessionreplay.utils.DefaultColorStringFormatter diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt index ae0faebb7f..c5ba0d978e 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt @@ -18,7 +18,7 @@ import android.widget.ImageView import com.datadog.android.api.InternalLogger import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.utils.ImageViewUtils +import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.SystemInformation @@ -117,7 +117,7 @@ internal class ImageViewMapperTest { lateinit var mockBackgroundConstantState: ConstantState @Mock - lateinit var stubClipping: MobileSegment.WireframeClip + lateinit var stubClipping: Rect @Mock lateinit var stubParentRect: Rect diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt index 4242325e1b..3115fa03b4 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt @@ -8,7 +8,7 @@ package com.datadog.android.sessionreplay.utils import android.view.View import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.sessionreplay.internal.recorder.densityNormalized +import com.datadog.android.internal.utils.densityNormalized import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension From be663eb7b2c053bd5cedf8112de9fbb1c60816fc Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Tue, 10 Dec 2024 12:05:49 +0100 Subject: [PATCH 7/9] Minor fixes to DefaultImageWireframeHelperTest test titles --- .../resources/DefaultImageWireframeHelperTest.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt index f98dd73453..2823a1b1ee 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt @@ -513,7 +513,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not return image wireframe W createImageWireframe(usePIIPlaceholder = true) { ImagePrivacy MASK_NONE }`() { + fun `M not return image wireframe W createImageWireframeByDrawable(usePIIPlaceholder = true) { ImagePrivacy MASK_NONE }`() { // When val wireframe = testedHelper.createImageWireframeByDrawable( view = mockView, @@ -536,7 +536,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not return image wireframe W createImageWireframe { ImagePrivacy MASK_LARGE_ONLY & isContextual image}`() { + fun `M not return image wireframe W createImageWireframeByBitmap { ImagePrivacy MASK_LARGE_ONLY & isContextual image}`() { // When val wireframe = testedHelper.createImageWireframeByBitmap( id = fakeViewId, @@ -555,7 +555,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return null W createImageWireframe() { application context is null }`() { + fun `M return null W createImageWireframeByDrawable() { application context is null }`() { // Given whenever(mockView.context.applicationContext).thenReturn(null) @@ -959,7 +959,7 @@ internal class DefaultImageWireframeHelperTest { } verify(mockAsyncJobStatusCallback, times(2)).jobStarted() verify(mockAsyncJobStatusCallback, times(2)).jobFinished() - assertThat(wireframes.size).isEqualTo(2) + assertThat(wireframes).hasSize(2) } @Test @@ -1067,7 +1067,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not try to resolve bitmap W createImageWireframe() { PII image }`( + fun `M not try to resolve bitmap W createImageWireframeByDrawable() { PII image }`( forge: Forge, @Mock mockResources: Resources, @Mock mockDisplayMetrics: DisplayMetrics, @@ -1115,7 +1115,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M try to resolve bitmap W createImageWireframe() { non-PII image }`() { + fun `M try to resolve bitmap W createImageWireframeByDrawable() { non-PII image }`() { // Given whenever(mockImageTypeResolver.isDrawablePII(any(), any())).thenReturn(false) @@ -1151,7 +1151,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M return content placeholder W createImageWireframe() { PII image }`() { + fun `M return content placeholder W createImageWireframeByDrawable() { PII image }`() { // Given whenever(mockImageTypeResolver.isDrawablePII(any(), any())).thenReturn(true) From bf7e7da46a097f59e9086ca2da0b0fa557abea69 Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Tue, 10 Dec 2024 12:13:36 +0100 Subject: [PATCH 8/9] Minor improvements to unit tests --- .../android/internal/utils/ImageViewUtils.kt | 24 +++++++++++++++++++ .../sessionreplay/internal/utils/RectExt.kt | 2 +- .../recorder/mapper/ImageViewMapper.kt | 1 - .../DefaultImageWireframeHelperTest.kt | 12 ++++++---- .../internal/utils/DrawableUtilsTest.kt | 24 ------------------- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt index 589e065f8d..b8a35b3496 100644 --- a/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt +++ b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ImageViewUtils.kt @@ -11,7 +11,17 @@ import android.graphics.drawable.Drawable import android.view.View import android.widget.ImageView +/** + * A collection of view utility functions for resolving absolute + * positions, clipping bounds, and other useful data for + * image views operations. + */ object ImageViewUtils { + /** + * Resolves the absolute position on the screen of the given [View]. + * @param view: the [View]. + * @return the [Rect] representing the absolute position of the view. + */ fun resolveParentRectAbsPosition(view: View): Rect { val coords = IntArray(2) // this will always have size >= 2 @@ -29,6 +39,14 @@ object ImageViewUtils { ) } + /** + * Calculates the clipping [Rect] of the given child [Rect] using its parent [Rect] and + * the screen density. + * @param parentRect: the parent [Rect]. + * @param childRect: the child [Rect]. + * @param density: the screen density. + * @return the clipping [Rect]. + */ fun calculateClipping(parentRect: Rect, childRect: Rect, density: Float): Rect { val left = if (childRect.left < parentRect.left) { parentRect.left - childRect.left @@ -58,6 +76,12 @@ object ImageViewUtils { ) } + /** + * Resolves the [Drawable] content [Rect] using the given [ImageView] scale type. + * @param imageView: the [ImageView]. + * @param drawable: the [Drawable]. + * @return the resolved content [Rect]. + */ fun resolveContentRectWithScaling( imageView: ImageView, drawable: Drawable diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt index f67ffd8edd..d60e440d7f 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/utils/RectExt.kt @@ -16,4 +16,4 @@ internal fun Rect.toWireframeClip(): MobileSegment.WireframeClip { this.left.toLong(), this.right.toLong() ) -} \ No newline at end of file +} diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt index 63f3cd82f5..b080a898df 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapper.kt @@ -11,7 +11,6 @@ import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.internal.utils.densityNormalized -import com.datadog.android.sessionreplay.SessionReplay import com.datadog.android.sessionreplay.internal.utils.toWireframeClip import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt index 2823a1b1ee..f08fbcece9 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt @@ -891,7 +891,8 @@ internal class DefaultImageWireframeHelperTest { customResourceIdCacheKey = null, asyncJobStatusCallback = mockAsyncJobStatusCallback ) - wireframes[0] as MobileSegment.Wireframe.ImageWireframe + + assertThat(wireframes[0]).isInstanceOf(MobileSegment.Wireframe.ImageWireframe::class.java) // Then val argumentCaptor = argumentCaptor() @@ -939,7 +940,8 @@ internal class DefaultImageWireframeHelperTest { customResourceIdCacheKey = null, asyncJobStatusCallback = mockAsyncJobStatusCallback ) - wireframes[0] as MobileSegment.Wireframe.ImageWireframe + + assertThat(wireframes[0]).isInstanceOf(MobileSegment.Wireframe.ImageWireframe::class.java) // Then val argumentCaptor = argumentCaptor() @@ -1270,7 +1272,8 @@ internal class DefaultImageWireframeHelperTest { customResourceIdCacheKey = null, asyncJobStatusCallback = mockAsyncJobStatusCallback ) - wireframes[0] as MobileSegment.Wireframe.ImageWireframe + + assertThat(wireframes[0]).isInstanceOf(MobileSegment.Wireframe.ImageWireframe::class.java) // Then val argumentCaptor = argumentCaptor() @@ -1318,7 +1321,8 @@ internal class DefaultImageWireframeHelperTest { customResourceIdCacheKey = null, asyncJobStatusCallback = mockAsyncJobStatusCallback ) - wireframes[0] as MobileSegment.Wireframe.ImageWireframe + + assertThat(wireframes[0]).isInstanceOf(MobileSegment.Wireframe.ImageWireframe::class.java) // Then val argumentCaptor = argumentCaptor() diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt index fb072896d3..60b419f7da 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/DrawableUtilsTest.kt @@ -33,7 +33,6 @@ import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doAnswer import org.mockito.kotlin.mock -import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.mockito.quality.Strictness @@ -372,29 +371,6 @@ internal class DrawableUtilsTest { assertThat(displayMetricsCaptor.firstValue).isEqualTo(mockDisplayMetrics) } - @Test - fun `M uses original drawable W createBitmapOfApproxSizeFromDrawable`() { - // Given - whenever(mockDrawable.intrinsicWidth).thenReturn(1) - whenever(mockDrawable.intrinsicHeight).thenReturn(1) - - // When - testedDrawableUtils.createBitmapOfApproxSizeFromDrawable( - drawable = mockDrawable, - drawableWidth = mockDrawable.intrinsicWidth, - drawableHeight = mockDrawable.intrinsicHeight, - displayMetrics = mockDisplayMetrics, - config = mockConfig, - bitmapCreationCallback = mockBitmapCreationCallback - ) - - // Then - verify(mockDrawable).setBounds(any(), any(), any(), any()) - verify(mockDrawable).draw(any()) - verify(mockSecondDrawable, never()).setBounds(any(), any(), any(), any()) - verify(mockSecondDrawable, never()).draw(any()) - } - @Test fun `M return scaled bitmap W createScaledBitmap()`( @Mock mockScaledBitmap: Bitmap From 5349533c0da88ff781dcda9db4625a5dd4dee4fa Mon Sep 17 00:00:00 2001 From: Marco Saia Date: Tue, 10 Dec 2024 14:54:37 +0100 Subject: [PATCH 9/9] Fixed ktlint issues --- .../android/sessionreplay/internal/DefaultRecorderProvider.kt | 2 +- .../internal/recorder/callback/RecorderWindowCallback.kt | 2 +- .../internal/recorder/mapper/ProgressBarWireframeMapper.kt | 2 +- .../internal/recorder/mapper/SeekBarWireframeMapper.kt | 2 +- .../recorder/resources/DefaultImageWireframeHelper.kt | 2 +- .../android/sessionreplay/recorder/mapper/TextViewMapper.kt | 2 +- .../internal/recorder/mapper/BaseSwitchCompatMapperTest.kt | 2 +- .../recorder/mapper/ProgressBarWireframeMapperTest.kt | 2 +- .../internal/recorder/mapper/SeekBarWireframeMapperTest.kt | 2 +- .../internal/recorder/mapper/SwitchCompatMapperTest.kt | 2 +- .../recorder/resources/DefaultImageWireframeHelperTest.kt | 4 ++-- .../android/sessionreplay/internal/utils/MiscUtilsTest.kt | 2 +- .../sessionreplay/recorder/mapper/ImageViewMapperTest.kt | 2 +- .../sessionreplay/utils/DefaultViewBoundsResolverTest.kt | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt index a2eaa226b1..d73d4e15b3 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/DefaultRecorderProvider.kt @@ -22,6 +22,7 @@ import android.widget.TextView import androidx.appcompat.widget.ActionBarContainer import androidx.appcompat.widget.SwitchCompat import com.datadog.android.api.feature.FeatureSdkCore +import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.MapperTypeWrapper import com.datadog.android.sessionreplay.TextAndInputPrivacy @@ -41,7 +42,6 @@ import com.datadog.android.sessionreplay.internal.resources.ResourceDataStoreMan import com.datadog.android.sessionreplay.internal.storage.RecordWriter import com.datadog.android.sessionreplay.internal.storage.ResourcesWriter import com.datadog.android.sessionreplay.internal.time.SessionReplayTimeProvider -import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.recorder.OptionSelectorDetector import com.datadog.android.sessionreplay.recorder.mapper.EditTextMapper import com.datadog.android.sessionreplay.recorder.mapper.ImageViewMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt index bca8604426..0c60391473 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/callback/RecorderWindowCallback.kt @@ -12,13 +12,13 @@ import android.view.MotionEvent import android.view.Window import androidx.annotation.MainThread import com.datadog.android.api.InternalLogger +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.internal.TouchPrivacyManager import com.datadog.android.sessionreplay.internal.async.RecordedDataQueueHandler import com.datadog.android.sessionreplay.internal.recorder.ViewOnDrawInterceptor import com.datadog.android.sessionreplay.internal.recorder.WindowInspector -import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.utils.TimeProvider import com.datadog.android.sessionreplay.model.MobileSegment import java.util.LinkedList diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt index d72c27771a..f5ba0fdfc8 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapper.kt @@ -14,8 +14,8 @@ import android.widget.ProgressBar import androidx.annotation.RequiresApi import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.internal.utils.densityNormalized +import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.mapper.BaseAsyncBackgroundWireframeMapper diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt index 5b550a91d5..e3cce77f8e 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapper.kt @@ -8,8 +8,8 @@ package com.datadog.android.sessionreplay.internal.recorder.mapper import android.widget.SeekBar import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.internal.utils.densityNormalized +import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt index 27e7e7c8ea..d9bae6304e 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelper.kt @@ -15,9 +15,9 @@ import android.widget.TextView import androidx.annotation.UiThread import androidx.annotation.VisibleForTesting import com.datadog.android.api.InternalLogger +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.internal.recorder.ViewUtilsInternal -import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.resources.DrawableCopier diff --git a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt index d0b6d8d27a..289e66e44d 100644 --- a/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt +++ b/features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/recorder/mapper/TextViewMapper.kt @@ -11,8 +11,8 @@ import android.view.Gravity import android.widget.TextView import androidx.annotation.UiThread import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.internal.utils.densityNormalized +import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.internal.recorder.obfuscator.StringObfuscator import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt index f2e053a3c1..e3a7e09327 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseSwitchCompatMapperTest.kt @@ -11,9 +11,9 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable.ConstantState import androidx.appcompat.widget.SwitchCompat +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper import com.datadog.android.sessionreplay.utils.GlobalBounds diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt index 26f09c0188..31da2a5dad 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/ProgressBarWireframeMapperTest.kt @@ -4,9 +4,9 @@ import android.content.res.ColorStateList import android.graphics.Rect import android.os.Build import android.widget.ProgressBar +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.recorder.mapper.SeekBarWireframeMapper.Companion.TRACK_HEIGHT_IN_PX import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.AbstractWireframeMapperTest diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt index cb59ba0627..638ba063a8 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SeekBarWireframeMapperTest.kt @@ -5,9 +5,9 @@ import android.graphics.Rect import android.graphics.drawable.Drawable import android.os.Build import android.widget.SeekBar +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.internal.recorder.mapper.SeekBarWireframeMapper.Companion.TRACK_HEIGHT_IN_PX import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.mapper.AbstractWireframeMapperTest diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt index 8d7c146332..b93ef068a9 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapperTest.kt @@ -7,10 +7,10 @@ package com.datadog.android.sessionreplay.internal.recorder.mapper import android.graphics.drawable.Drawable +import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.TextAndInputPrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.internal.utils.densityNormalized import com.datadog.android.sessionreplay.model.MobileSegment import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeConfiguration diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt index f08fbcece9..2b8416a3d5 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DefaultImageWireframeHelperTest.kt @@ -513,7 +513,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not return image wireframe W createImageWireframeByDrawable(usePIIPlaceholder = true) { ImagePrivacy MASK_NONE }`() { + fun `M not return image wireframe W createImageWireframeByDrawable(usePIIPlaceholder = true) { MASK_NONE }`() { // When val wireframe = testedHelper.createImageWireframeByDrawable( view = mockView, @@ -536,7 +536,7 @@ internal class DefaultImageWireframeHelperTest { } @Test - fun `M not return image wireframe W createImageWireframeByBitmap { ImagePrivacy MASK_LARGE_ONLY & isContextual image}`() { + fun `M not return image wireframe W createImageWireframeByBitmap { MASK_LARGE_ONLY & isContextual image}`() { // When val wireframe = testedHelper.createImageWireframeByBitmap( id = fakeViewId, diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt index 94a2d91c29..1d2c73c720 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/utils/MiscUtilsTest.kt @@ -19,8 +19,8 @@ import android.view.Display import android.view.WindowManager import android.view.WindowMetrics import com.datadog.android.api.InternalLogger -import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.internal.utils.densityNormalized +import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.sessionreplay.internal.utils.MiscUtils.DESERIALIZE_JSON_ERROR import com.datadog.android.sessionreplay.recorder.SystemInformation import com.datadog.android.sessionreplay.utils.DefaultColorStringFormatter diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt index c5ba0d978e..ae4891ec68 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/recorder/mapper/ImageViewMapperTest.kt @@ -16,9 +16,9 @@ import android.util.DisplayMetrics import android.view.View import android.widget.ImageView import com.datadog.android.api.InternalLogger +import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.ImagePrivacy import com.datadog.android.sessionreplay.forge.ForgeConfigurator -import com.datadog.android.internal.utils.ImageViewUtils import com.datadog.android.sessionreplay.model.MobileSegment import com.datadog.android.sessionreplay.recorder.MappingContext import com.datadog.android.sessionreplay.recorder.SystemInformation diff --git a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt index 3115fa03b4..69eab2fcaf 100644 --- a/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt +++ b/features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/utils/DefaultViewBoundsResolverTest.kt @@ -7,8 +7,8 @@ package com.datadog.android.sessionreplay.utils import android.view.View -import com.datadog.android.sessionreplay.forge.ForgeConfigurator import com.datadog.android.internal.utils.densityNormalized +import com.datadog.android.sessionreplay.forge.ForgeConfigurator import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension