Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f99d783
PANA-8391: Add embedded content wireframe model support
jonathanmos Jul 28, 2026
ca508d7
PANA-8391: Prevent hidden embedded content from occluding wireframes
jonathanmos Jul 29, 2026
f84dec5
Merge pull request #3678 from DataDog/jmoskovich/01-flutter-support
jonathanmos Jul 29, 2026
a819ef2
Merge remote-tracking branch 'origin/develop' into jmoskovich/merge-d…
jonathanmos Jul 30, 2026
3376f37
Merge pull request #3684 from DataDog/jmoskovich/merge-develop-into-f…
jonathanmos Jul 30, 2026
6db684b
Merge branch 'develop' into jmoskovich/merge-develop-into-flutter-sup…
jonathanmos Aug 4, 2026
fc14c74
Merge pull request #3694 from DataDog/jmoskovich/merge-develop-into-f…
jonathanmos Aug 4, 2026
0df2040
PANA-8412: Add embedded content bridge APIs
jonathanmos Jul 30, 2026
40e3a99
PANA-8412: Record embedded content wireframes
jonathanmos Jul 30, 2026
9903d3a
PANA-8412: Receive embedded Session Replay data
jonathanmos Jul 30, 2026
211dfb0
PANA-8412: Track embedded records across RUM views
jonathanmos Jul 30, 2026
98149ff
PANA-8412: PR fixes
jonathanmos Aug 4, 2026
8b6c2f3
PANA-8412: Scope embedded slot registry to feature
jonathanmos Aug 4, 2026
6f464b9
PANA-8412: Process embedded content asynchronously
jonathanmos Aug 10, 2026
f177053
PANA-8412: Address embedded content review feedback
jonathanmos Aug 10, 2026
5b41f07
PANA-8412: Order Flutter records after their placeholder wireframe
JuanNaranjoDD Aug 19, 2026
1c93ebf
PANA-8412: feedback addressed
JuanNaranjoDD Aug 24, 2026
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
1 change: 1 addition & 0 deletions detekt_custom_safe_calls_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ datadog:
- "android.view.View.hashCode()"
- "android.view.View.onDraw(android.graphics.Canvas)"
- "android.view.View.performClick()"
- "android.view.View.postInvalidateOnAnimation()"
- "android.view.View.post(java.lang.Runnable?)"
- "android.view.View.removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener?)"
- "android.view.View.setOnClickListener(android.view.View.OnClickListener?)"
Expand Down
15 changes: 15 additions & 0 deletions detekt_custom_safe_calls_third_party.yml
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ datadog:
- "java.lang.ref.WeakReference.constructor(android.view.Window?)"
- "java.lang.ref.WeakReference.constructor(com.datadog.android.api.SdkCore?)"
- "java.lang.ref.WeakReference.constructor(com.datadog.android.rum.tracking.ViewTarget?)"
- "java.lang.ref.WeakReference.constructor(com.datadog.android.sessionreplay.internal.embedded.EmbeddedContentSlotRegistration?)"
- "java.lang.ref.WeakReference.constructor(kotlin.Any?)"
- "java.lang.ref.WeakReference.constructor(kotlin.Nothing?)"
- "java.lang.ref.WeakReference.constructor(kotlin.String?)"
Expand Down Expand Up @@ -461,8 +462,11 @@ datadog:
- "kotlin.collections.ArrayList(kotlin.collections.MutableCollection?)"
- "kotlin.collections.buildMap(kotlin.Function1)"
- "kotlin.collections.Collection.flatten()"
- "kotlin.collections.Collection.firstOrNull()"
- "kotlin.collections.Collection.fold(kotlin.collections.MutableSet, kotlin.Function2)"
- "kotlin.collections.Collection.forEach(kotlin.Function1)"
- "kotlin.collections.Collection.groupBy(kotlin.Function1)"
- "kotlin.collections.Collection.mapNotNull(kotlin.Function1)"
- "kotlin.collections.Collection.isNotEmpty()"
- "kotlin.collections.Collection.sumOf(kotlin.Function1)"
- "kotlin.collections.Collection.toList()"
Expand Down Expand Up @@ -502,6 +506,7 @@ datadog:
- "kotlin.collections.List.firstOrNull(kotlin.Function1)"
- "kotlin.collections.List.firstNotNullOfOrNull(kotlin.Function1)"
- "kotlin.collections.List.flatMap(kotlin.Function1)"
- "kotlin.collections.List.flatten()"
- "kotlin.collections.List.fold(com.google.gson.JsonArray, kotlin.Function2)"
- "kotlin.collections.List.fold(kotlin.Long, kotlin.Function2)"
- "kotlin.collections.List.fold(kotlin.String?, kotlin.Function2)"
Expand All @@ -519,10 +524,12 @@ datadog:
- "kotlin.collections.List.lastOrNull()"
- "kotlin.collections.List.lastOrNull(kotlin.Function1)"
- "kotlin.collections.List.map(kotlin.Function1)"
- "kotlin.collections.List.mapTo(kotlin.collections.MutableSet, kotlin.Function1)"
- "kotlin.collections.List.mapIndexed(kotlin.Function2)"
- "kotlin.collections.List.mapNotNull(kotlin.Function1)"
- "kotlin.collections.List.maxByOrNull(kotlin.Function1)"
- "kotlin.collections.List.maxOrNull()"
- "kotlin.collections.List.minOrNull()"
- "kotlin.collections.List.orEmpty()"
- "kotlin.collections.List.partition(kotlin.Function1)"
- "kotlin.collections.List.reduceOrNull(kotlin.Function2)"
Expand Down Expand Up @@ -571,6 +578,7 @@ datadog:
- "kotlin.collections.MutableCollection.flatMap(kotlin.Function1)"
- "kotlin.collections.MutableCollection.forEach(kotlin.Function1)"
- "kotlin.collections.MutableCollection.toList()"
- "kotlin.collections.MutableCollection.toSet()"
- "kotlin.collections.MutableIterator.forEach(kotlin.Function1)"
- "kotlin.collections.MutableIterator.hasNext()"
- "kotlin.collections.MutableList.add(com.datadog.android.api.InternalLogger.Target)"
Expand All @@ -587,6 +595,7 @@ datadog:
- "kotlin.collections.MutableList.add(com.datadog.android.rum.model.ActionEvent.Type)"
- "kotlin.collections.MutableList.add(com.datadog.android.sessionreplay.compose.internal.data.Parameter)"
- "kotlin.collections.MutableList.add(com.datadog.android.sessionreplay.compose.internal.utils.BackgroundInfo)"
- "kotlin.collections.MutableList.add(com.datadog.android.sessionreplay.internal.embedded.PendingBatch)"
- "kotlin.collections.MutableList.add(com.datadog.android.sessionreplay.internal.prerequisite.SystemRequirementChecker)"
- "kotlin.collections.MutableList.add(com.datadog.android.sessionreplay.internal.processor.MutationResolver.Entry)"
- "kotlin.collections.MutableList.add(com.datadog.android.sessionreplay.model.MobileSegment.Add)"
Expand All @@ -606,6 +615,7 @@ datadog:
- "kotlin.collections.MutableList.add(kotlin.Int, com.datadog.android.sessionreplay.model.MobileSegment.Wireframe)"
- "kotlin.collections.MutableList.add(kotlin.Int, com.datadog.android.sessionreplay.model.MobileSegment.Wireframe.ShapeWireframe)"
- "kotlin.collections.MutableList.add(kotlin.String)"
- "kotlin.collections.MutableList.add(kotlin.Function1)"
- "kotlin.collections.MutableList.addAll(kotlin.collections.Collection)"
- "kotlin.collections.MutableList.any(kotlin.Function1)"
- "kotlin.collections.MutableList.clear()"
Expand All @@ -623,6 +633,7 @@ datadog:
- "kotlin.collections.MutableList.iterator()"
- "kotlin.collections.MutableList.joinToString(kotlin.CharSequence, kotlin.CharSequence, kotlin.CharSequence, kotlin.Int, kotlin.CharSequence, kotlin.Function1?)"
- "kotlin.collections.MutableList.map(kotlin.Function1)"
- "kotlin.collections.MutableList.mapNotNullTo(kotlin.collections.MutableSet, kotlin.Function1)"
- "kotlin.collections.MutableList.partition(kotlin.Function1)"
- "kotlin.collections.MutableList.remove(java.io.File)"
- "kotlin.collections.MutableList.remove(java.lang.ref.WeakReference)"
Expand Down Expand Up @@ -699,7 +710,10 @@ datadog:
- "kotlin.collections.MutableSet.contains(com.datadog.android.telemetry.internal.TelemetryEventId)"
- "kotlin.collections.MutableSet.contains(kotlin.String)"
- "kotlin.collections.MutableSet.contains(kotlin.String?)"
- "kotlin.collections.MutableSet.isEmpty()"
- "kotlin.collections.MutableSet.remove(kotlin.String)"
- "kotlin.collections.MutableSet.filter(kotlin.Function1)"
- "kotlin.collections.MutableSet.firstOrNull()"
- "kotlin.collections.MutableSet.firstOrNull(kotlin.Function1)"
- "kotlin.collections.MutableSet.flatMap(kotlin.Function1)"
- "kotlin.collections.MutableSet.forEach(kotlin.Function1)"
Expand All @@ -713,6 +727,7 @@ datadog:
- "kotlin.collections.MutableSet.remove(java.io.File)"
- "kotlin.collections.MutableSet.remove(kotlin.collections.MutableMap.Mutab(...)"
- "kotlin.collections.MutableSet.removeAll(kotlin.collections.Collection)"
- "kotlin.collections.MutableSet.retainAll(kotlin.collections.Collection)"
- "kotlin.collections.MutableSet.toList()"
- "kotlin.collections.MutableSet.lastOrNull()"
- "kotlin.collections.MutableSet.sortedByDescending(kotlin.Function1)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,16 +400,18 @@ class RootSemanticsNodeMapperTest {
}

@Test
fun `M call interop callback W semantics node has interop view`(forge: Forge) {
fun `M preserve embedded wireframe W semantics node has interop view`(forge: Forge) {
// Given
val mockSemanticsNode = mockSemanticsNode(null)
val mockView = mock<View>()
val fakeInteropWireframe = MobileSegment.Wireframe.ShapeWireframe(
val fakeInteropWireframe = MobileSegment.Wireframe.EmbeddedContentWireframe(
id = forge.aLong(),
x = forge.aLong(min = 0, max = 500),
y = forge.aLong(min = 0, max = 500),
width = forge.aLong(min = 1, max = 500),
height = forge.aLong(min = 1, max = 500)
height = forge.aLong(min = 1, max = 500),
slotId = forge.anAlphabeticalString(),
isVisible = true
)
whenever(mockSemanticsUtils.getInteropView(mockSemanticsNode)) doReturn mockView
whenever(fakeMappingContext.interopViewCallback.map(mockView, fakeMappingContext))
Expand Down
23 changes: 21 additions & 2 deletions features/dd-sdk-android-session-replay/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const val WIREFRAME_TYPE_TEXT: String
const val WIREFRAME_TYPE_IMAGE: String
const val WIREFRAME_TYPE_PLACEHOLDER: String
const val WIREFRAME_TYPE_WEBVIEW: String
const val WIREFRAME_TYPE_EMBEDDED_CONTENT: String
const val IMAGE_DIMEN_CONSIDERED_PII_IN_DP: Int
interface com.datadog.android.sessionreplay.PrivacyLevel
fun android.view.View.setSessionReplayHidden(Boolean)
Expand Down Expand Up @@ -77,6 +78,10 @@ enum com.datadog.android.sessionreplay.TouchPrivacy : PrivacyLevel
class com.datadog.android.sessionreplay._SessionReplayInternalProxy
constructor(SessionReplayConfiguration.Builder)
fun setInternalCallback(SessionReplayInternalCallback): SessionReplayConfiguration.Builder
companion object
fun setEmbeddedContentSlotId(android.view.View, String?)
fun addEmbeddedContentRecords(List<Map<String, Any?>>, String, String, com.datadog.android.api.SdkCore = Datadog.getInstance())
fun addEmbeddedContentResource(String, ByteArray, String, com.datadog.android.api.SdkCore = Datadog.getInstance())
class com.datadog.android.sessionreplay.internal.TouchPrivacyManager
constructor(com.datadog.android.sessionreplay.TouchPrivacy)
fun addTouchOverrideArea(android.graphics.Rect, com.datadog.android.sessionreplay.TouchPrivacy)
Expand Down Expand Up @@ -192,14 +197,14 @@ data class com.datadog.android.sessionreplay.model.MobileSegment
sealed class MobileRecord
abstract fun toJson(): com.google.gson.JsonElement
data class MobileFullSnapshotRecord : MobileRecord
constructor(kotlin.Long, Data)
constructor(kotlin.Long, Data, kotlin.String? = null)
val type: kotlin.Long
override fun toJson(): com.google.gson.JsonElement
companion object
fun fromJson(kotlin.String): MobileFullSnapshotRecord
fun fromJsonObject(com.google.gson.JsonObject): MobileFullSnapshotRecord
data class MobileIncrementalSnapshotRecord : MobileRecord
constructor(kotlin.Long, MobileIncrementalData)
constructor(kotlin.Long, MobileIncrementalData, kotlin.String? = null)
val type: kotlin.Long
override fun toJson(): com.google.gson.JsonElement
companion object
Expand Down Expand Up @@ -330,6 +335,13 @@ data class com.datadog.android.sessionreplay.model.MobileSegment
companion object
fun fromJson(kotlin.String): WebviewWireframe
fun fromJsonObject(com.google.gson.JsonObject): WebviewWireframe
data class EmbeddedContentWireframe : Wireframe
constructor(kotlin.Long, kotlin.Long, kotlin.Long, kotlin.Long, kotlin.Long, WireframeClip? = null, ShapeStyle? = null, ShapeBorder? = null, kotlin.String, kotlin.Boolean? = null, kotlin.String? = null)
val type: kotlin.String
override fun toJson(): com.google.gson.JsonElement
companion object
fun fromJson(kotlin.String): EmbeddedContentWireframe
fun fromJsonObject(com.google.gson.JsonObject): EmbeddedContentWireframe
companion object
fun fromJson(kotlin.String): Wireframe
fun fromJsonElement(com.google.gson.JsonElement): Wireframe
Expand Down Expand Up @@ -382,6 +394,13 @@ data class com.datadog.android.sessionreplay.model.MobileSegment
companion object
fun fromJson(kotlin.String): WebviewWireframeUpdate
fun fromJsonObject(com.google.gson.JsonObject): WebviewWireframeUpdate
data class EmbeddedContentWireframeUpdate : WireframeUpdateMutation
constructor(kotlin.Long, kotlin.Long? = null, kotlin.Long? = null, kotlin.Long? = null, kotlin.Long? = null, WireframeClip? = null, ShapeStyle? = null, ShapeBorder? = null, kotlin.String, kotlin.Boolean? = null)
val type: kotlin.String
override fun toJson(): com.google.gson.JsonElement
companion object
fun fromJson(kotlin.String): EmbeddedContentWireframeUpdate
fun fromJsonObject(com.google.gson.JsonObject): EmbeddedContentWireframeUpdate
companion object
fun fromJson(kotlin.String): WireframeUpdateMutation
fun fromJsonElement(com.google.gson.JsonElement): WireframeUpdateMutation
Expand Down
Loading
Loading