Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare patch version to support React Native SR #2458

Merged
merged 4 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2.16.1 / 2024-12-18

* [IMPROVEMENT] Refactoring for React Native Session Replay support. See [#2448](https://github.com/DataDog/dd-sdk-android/pull/2448)

# 2.16.0 / 2024-11-20

* [FEATURE] Session Replay: Create Session Replay Compose module.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object AndroidConfig {
const val MIN_SDK_FOR_WEAR = 23
const val BUILD_TOOLS_VERSION = "35.0.0"

val VERSION = Version(2, 16, 0, Version.Type.Release)
val VERSION = Version(2, 16, 1, Version.Type.Release)
}

// TODO RUM-628 Switch to Java 17 bytecode
Expand Down
6 changes: 6 additions & 0 deletions dd-sdk-android-internal/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ sealed class com.datadog.android.internal.telemetry.InternalTelemetryEvent
constructor(Boolean, Boolean, Boolean, MutableMap<String, Any?> = 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.widget.ImageView.ScaleType? = null): 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)
16 changes: 16 additions & 0 deletions dd-sdk-android-internal/api/dd-sdk-android-internal.api
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,22 @@ 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/widget/ImageView$ScaleType;)Landroid/graphics/Rect;
public static synthetic fun resolveContentRectWithScaling$default (Lcom/datadog/android/internal/utils/ImageViewUtils;Landroid/widget/ImageView;Landroid/graphics/drawable/Drawable;Landroid/widget/ImageView$ScaleType;ILjava/lang/Object;)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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@
* 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 {
/**
* 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
@Suppress("UnsafeThirdPartyFunctionCall")
Expand All @@ -31,7 +39,15 @@ internal object ImageViewUtils {
)
}

internal fun calculateClipping(parentRect: Rect, childRect: Rect, density: Float): MobileSegment.WireframeClip {
/**
* 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
} else {
Expand All @@ -52,18 +68,25 @@ 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(
/**
* Resolves the [Drawable] content [Rect] using the given [ImageView] scale type.
* @param imageView the [ImageView].
* @param drawable the [Drawable].
* @param customScaleType optional custom [ImageView.ScaleType].
* @return the resolved content [Rect].
*/
fun resolveContentRectWithScaling(
imageView: ImageView,
drawable: Drawable
drawable: Drawable,
customScaleType: ImageView.ScaleType? = null
): Rect {
val drawableWidthPx = drawable.intrinsicWidth
val drawableHeightPx = drawable.intrinsicHeight
Expand All @@ -79,7 +102,7 @@ internal object ImageViewUtils {

val resultRect: Rect

when (imageView.scaleType) {
when (customScaleType ?: imageView.scaleType) {
ImageView.ScaleType.FIT_START -> {
val contentRect = scaleRectToFitParent(parentRect, childRect)
resultRect = positionRectAtStart(parentRect, contentRect)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ internal class ChipWireframeMapper(
height = view.chipDrawable.intrinsicHeight,
usePIIPlaceholder = false,
drawable = view.chipDrawable,
customResourceIdCacheKey = null,
asyncJobStatusCallback = asyncJobStatusCallback
)
backgroundWireframe?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.isNull
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
Expand Down Expand Up @@ -176,7 +176,8 @@ class ChipWireframeMapperTest {
clipping = isNull(),
shapeStyle = isNull(),
border = isNull(),
prefix = any()
prefix = any(),
customResourceIdCacheKey = anyOrNull()
)
}

Expand Down
18 changes: 11 additions & 7 deletions features/dd-sdk-android-session-replay/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@ 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
fun isOptionSelector(android.view.ViewGroup): Boolean
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<T: android.view.View> : BaseWireframeMapper<T>
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<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
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<T: android.view.ViewGroup> : BaseAsyncBackgroundWireframeMapper<T>, TraverseAllChildrenMapper<T>
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)
Expand All @@ -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<android.widget.ImageView>
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<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
open class com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper<T: android.widget.TextView> : BaseAsyncBackgroundWireframeMapper<T>
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)
Expand All @@ -93,6 +93,10 @@ open class com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper<T: a
interface com.datadog.android.sessionreplay.recorder.mapper.TraverseAllChildrenMapper<T: android.view.ViewGroup> : WireframeMapper<T>
interface com.datadog.android.sessionreplay.recorder.mapper.WireframeMapper<T: android.view.View>
fun map(T, com.datadog.android.sessionreplay.recorder.MappingContext, com.datadog.android.sessionreplay.utils.AsyncJobStatusCallback, com.datadog.android.api.InternalLogger): List<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
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<DrawableToColorMapper> = emptyList())
override fun resolveRippleDrawable(android.graphics.drawable.RippleDrawable, com.datadog.android.api.InternalLogger): Int?
Expand Down Expand Up @@ -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): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe?
fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, AsyncJobStatusCallback): MutableList<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
fun createImageWireframeByDrawable(android.view.View, com.datadog.android.sessionreplay.ImagePrivacy, Int, Long, Long, Int, Int, Boolean, android.graphics.drawable.Drawable, com.datadog.android.sessionreplay.recorder.resources.DrawableCopier = DefaultDrawableCopier(), AsyncJobStatusCallback, com.datadog.android.sessionreplay.model.MobileSegment.WireframeClip? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeStyle? = null, com.datadog.android.sessionreplay.model.MobileSegment.ShapeBorder? = null, String? = DRAWABLE_CHILD_NAME, String?): com.datadog.android.sessionreplay.model.MobileSegment.Wireframe?
fun createCompoundDrawableWireframes(android.widget.TextView, com.datadog.android.sessionreplay.recorder.MappingContext, Int, String?, AsyncJobStatusCallback): MutableList<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe>
companion object
open class com.datadog.android.sessionreplay.utils.LegacyDrawableToColorMapper : DrawableToColorMapper
constructor(List<DrawableToColorMapper> = emptyList())
Expand Down
Loading