Skip to content
Open
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: 2 additions & 2 deletions benchmarks/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ dependencies {

// Benchmark tools from dd-sdk-android are used for vitals recording
// Remember to bump this alongside the main dd-sdk-android dependencies
implementation("com.datadoghq:dd-sdk-android-benchmark-internal:3.15.0")
implementation("com.datadoghq:dd-sdk-android-benchmark-internal:3.16.0")
// Required for compile-time access to Datadog.getInstance() required by BenchmarkVitalsModuleImpl
implementation("com.datadoghq:dd-sdk-android-core:3.15.0")
implementation("com.datadoghq:dd-sdk-android-core:3.16.0")
}
18 changes: 9 additions & 9 deletions packages/core/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ dependencies {
// This breaks builds if the React Native target is below 0.76.0. as it relies on Gradle 8.5.0.
// To avoid this, we enforce 1.0.0-beta01 on RN < 0.76.0
if (reactNativeMinorVersion < 76) {
implementation("com.datadoghq:dd-sdk-android-rum:3.15.0") {
implementation("com.datadoghq:dd-sdk-android-rum:3.16.0") {
exclude group: "androidx.metrics", module: "metrics-performance"
}
implementation "androidx.metrics:metrics-performance:1.0.0-beta01"
Expand All @@ -242,15 +242,15 @@ dependencies {
}
}
} else {
implementation "com.datadoghq:dd-sdk-android-rum:3.15.0"
implementation "com.datadoghq:dd-sdk-android-rum:3.16.0"
}
implementation "com.datadoghq:dd-sdk-android-logs:3.15.0"
implementation "com.datadoghq:dd-sdk-android-trace:3.15.0"
implementation "com.datadoghq:dd-sdk-android-webview:3.15.0"
implementation "com.datadoghq:dd-sdk-android-ndk:3.15.0"
implementation "com.datadoghq:dd-sdk-android-flags:3.15.0"
implementation "com.datadoghq:dd-sdk-android-internal:3.15.0"
implementation "com.datadoghq:dd-sdk-android-rum-prelaunch:3.15.0"
implementation "com.datadoghq:dd-sdk-android-logs:3.16.0"
implementation "com.datadoghq:dd-sdk-android-trace:3.16.0"
implementation "com.datadoghq:dd-sdk-android-webview:3.16.0"
implementation "com.datadoghq:dd-sdk-android-ndk:3.16.0"
implementation "com.datadoghq:dd-sdk-android-flags:3.16.0"
implementation "com.datadoghq:dd-sdk-android-internal:3.16.0"
implementation "com.datadoghq:dd-sdk-android-rum-prelaunch:3.16.0"
implementation "com.google.code.gson:gson:2.11.0"
testImplementation "org.junit.platform:junit-platform-launcher:1.6.2"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.2"
Expand Down
2 changes: 1 addition & 1 deletion packages/internal-testing-tools/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ dependencies {
}
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(path: ':datadog_mobile-react-native')
implementation "com.datadoghq:dd-sdk-android-core:3.15.0"
implementation "com.datadoghq:dd-sdk-android-core:3.16.0"
implementation "com.google.code.gson:gson:2.11.0"

testImplementation "org.junit.platform:junit-platform-launcher:1.6.2"
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-session-replay/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ dependencies {
api "com.facebook.react:react-android:$reactNativeVersion"
}
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.datadoghq:dd-sdk-android-session-replay:3.15.0"
implementation "com.datadoghq:dd-sdk-android-internal:3.15.0"
implementation "com.datadoghq:dd-sdk-android-session-replay:3.16.0"
implementation "com.datadoghq:dd-sdk-android-internal:3.16.0"
implementation project(path: ':datadog_mobile-react-native')

testImplementation "org.junit.platform:junit-platform-launcher:1.6.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class DdSessionReplayImplementation(
* @param startRecordingImmediately Whether the recording should start immediately when the feature is enabled.
* @param enableHeatmaps Enables heatmap identifier computation.
* @param enableCompositionTreeRecording Enables the Composition Tree recording pipeline.
* @param adaptiveCaptureSchedulingEnabled Enables experimental adaptive capture scheduling on Android.
*/
@SuppressLint("VisibleForTests")
@Suppress("LongParameterList", "UNUSED_PARAMETER")
Expand All @@ -43,28 +44,30 @@ class DdSessionReplayImplementation(
startRecordingImmediately: Boolean,
enableHeatmaps: Boolean,
enableCompositionTreeRecording: Boolean,
adaptiveCaptureSchedulingEnabled: Boolean,
promise: Promise
) {
val sdkCore = Datadog.getInstance() as FeatureSdkCore
val logger = sdkCore.internalLogger
val textViewUtils = TextViewUtils.create(reactContext, logger)
val internalCallback = ReactNativeInternalCallback(reactContext)
val configuration = SessionReplayConfiguration.Builder(replaySampleRate.toFloat())
val configurationBuilder = SessionReplayConfiguration.Builder(replaySampleRate.toFloat())
.startRecordingImmediately(startRecordingImmediately)
.setImagePrivacy(privacySettings.imagePrivacyLevel)
.setTouchPrivacy(privacySettings.touchPrivacyLevel)
.setTextAndInputPrivacy(privacySettings.textAndInputPrivacyLevel)
.setHeatmapsEnabled(enableHeatmaps)
.addExtensionSupport(ReactNativeSessionReplayExtensionSupport(textViewUtils, internalCallback))
.let {
_SessionReplayInternalProxy(it).setInternalCallback(internalCallback)
}

val internalProxy = _SessionReplayInternalProxy(configurationBuilder)
internalProxy.setInternalCallback(internalCallback)
internalProxy.setAdaptiveCaptureSchedulingEnabled(adaptiveCaptureSchedulingEnabled)

if (customEndpoint != "") {
configuration.useCustomEndpoint(customEndpoint)
configurationBuilder.useCustomEndpoint(customEndpoint)
}

sessionReplayProvider().enable(configuration.build(), sdkCore)
sessionReplayProvider().enable(configurationBuilder.build(), sdkCore)
HeatmapActionHandler.heatmapsEnabled = enableHeatmaps

promise.resolve(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class DdSessionReplay(
* @param startRecordingImmediately Whether the recording should start immediately when the feature is enabled.
* @param enableHeatmaps Enables heatmap identifier computation.
* @param enableCompositionTreeRecording Enables the Composition Tree recording pipeline.
* @param adaptiveCaptureSchedulingEnabled Enables experimental adaptive capture scheduling on Android.
*/
@Suppress("LongParameterList")
@ReactMethod
Expand All @@ -43,20 +44,22 @@ class DdSessionReplay(
startRecordingImmediately: Boolean,
enableHeatmaps: Boolean,
enableCompositionTreeRecording: Boolean,
adaptiveCaptureSchedulingEnabled: Boolean,
promise: Promise
) {
implementation.enable(
replaySampleRate,
customEndpoint,
SessionReplayPrivacySettings(
replaySampleRate = replaySampleRate,
customEndpoint = customEndpoint,
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacyLevel,
touchPrivacyLevel = touchPrivacyLevel,
textAndInputPrivacyLevel = textAndInputPrivacyLevel
),
startRecordingImmediately,
enableHeatmaps,
enableCompositionTreeRecording,
promise
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = enableHeatmaps,
enableCompositionTreeRecording = enableCompositionTreeRecording,
adaptiveCaptureSchedulingEnabled = adaptiveCaptureSchedulingEnabled,
promise = promise
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class DdSessionReplay(
* @param startRecordingImmediately Whether the recording should start immediately when the feature is enabled.
* @param enableHeatmaps Enables heatmap identifier computation.
* @param enableCompositionTreeRecording Enables the Composition Tree recording pipeline.
* @param adaptiveCaptureSchedulingEnabled Enables experimental adaptive capture scheduling on Android.
*/
@Suppress("LongParameterList")
@ReactMethod
Expand All @@ -44,20 +45,22 @@ class DdSessionReplay(
startRecordingImmediately: Boolean,
enableHeatmaps: Boolean,
enableCompositionTreeRecording: Boolean,
adaptiveCaptureSchedulingEnabled: Boolean,
promise: Promise
) {
implementation.enable(
replaySampleRate,
customEndpoint,
SessionReplayPrivacySettings(
replaySampleRate = replaySampleRate,
customEndpoint = customEndpoint,
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacyLevel,
touchPrivacyLevel = touchPrivacyLevel,
textAndInputPrivacyLevel = textAndInputPrivacyLevel
),
startRecordingImmediately,
enableHeatmaps,
enableCompositionTreeRecording,
promise
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = enableHeatmaps,
enableCompositionTreeRecording = enableCompositionTreeRecording,
adaptiveCaptureSchedulingEnabled = adaptiveCaptureSchedulingEnabled,
promise = promise
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.Extensions
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
Expand Down Expand Up @@ -132,13 +134,18 @@ internal class DdSessionReplayImplementationTest {

// When
testedSessionReplay.enable(
replaySampleRate,
customEndpoint,
SessionReplayPrivacySettings(imagePrivacy, touchPrivacy, textAndInputPrivacy),
startRecordingImmediately,
false,
false,
mockPromise
replaySampleRate = replaySampleRate,
customEndpoint = customEndpoint,
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = false,
enableCompositionTreeRecording = false,
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)

// Then
Expand All @@ -164,17 +171,18 @@ internal class DdSessionReplayImplementationTest {

// When
testedSessionReplay.enable(
replaySampleRate,
"",
SessionReplayPrivacySettings(
replaySampleRate = replaySampleRate,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately,
false,
false,
mockPromise
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = false,
enableCompositionTreeRecording = false,
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)

// Then
Expand All @@ -186,6 +194,32 @@ internal class DdSessionReplayImplementationTest {
.doesNotHaveField("customEndpointUrl")
}

@ParameterizedTest
@ValueSource(booleans = [true, false])
fun `M configure adaptive capture scheduling W enable`(enabled: Boolean) {
val sessionReplayConfigCaptor = argumentCaptor<SessionReplayConfiguration>()

testedSessionReplay.enable(
replaySampleRate = 100.0,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = "MASK_ALL",
touchPrivacyLevel = "HIDE",
textAndInputPrivacyLevel = "MASK_ALL"
),
startRecordingImmediately = true,
enableHeatmaps = false,
enableCompositionTreeRecording = false,
adaptiveCaptureSchedulingEnabled = enabled,
promise = mockPromise
)

verify(mockSessionReplay).enable(sessionReplayConfigCaptor.capture(), any())
assertThat(sessionReplayConfigCaptor.firstValue)
.hasFieldEqualTo("adaptiveCaptureSchedulingEnabled", enabled)
verify(mockPromise).resolve(null)
}

// region enableHeatmaps flag

@Test
Expand All @@ -200,13 +234,18 @@ internal class DdSessionReplayImplementationTest {

// When
testedSessionReplay.enable(
replaySampleRate,
"",
SessionReplayPrivacySettings(imagePrivacy, touchPrivacy, textAndInputPrivacy),
startRecordingImmediately,
replaySampleRate = replaySampleRate,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = true,
enableCompositionTreeRecording = false,
mockPromise
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)

// Then
Expand All @@ -226,13 +265,18 @@ internal class DdSessionReplayImplementationTest {

// When
testedSessionReplay.enable(
replaySampleRate,
"",
SessionReplayPrivacySettings(imagePrivacy, touchPrivacy, textAndInputPrivacy),
startRecordingImmediately,
replaySampleRate = replaySampleRate,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = false,
enableCompositionTreeRecording = false,
mockPromise
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)

// Then
Expand All @@ -252,13 +296,18 @@ internal class DdSessionReplayImplementationTest {

// When
testedSessionReplay.enable(
replaySampleRate,
"",
SessionReplayPrivacySettings(imagePrivacy, touchPrivacy, textAndInputPrivacy),
startRecordingImmediately,
replaySampleRate = replaySampleRate,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = true,
enableCompositionTreeRecording = false,
mockPromise
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)

// Then — heatmapsEnabled is true in the built SessionReplayConfiguration
Expand All @@ -280,13 +329,18 @@ internal class DdSessionReplayImplementationTest {

// When
testedSessionReplay.enable(
replaySampleRate,
"",
SessionReplayPrivacySettings(imagePrivacy, touchPrivacy, textAndInputPrivacy),
startRecordingImmediately,
replaySampleRate = replaySampleRate,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = false,
enableCompositionTreeRecording = false,
mockPromise
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)

// Then — heatmapsEnabled is false in the built SessionReplayConfiguration
Expand All @@ -309,13 +363,18 @@ internal class DdSessionReplayImplementationTest {
// When / Then
assertThrows(IllegalStateException::class.java) {
testedSessionReplay.enable(
replaySampleRate,
"",
SessionReplayPrivacySettings(imagePrivacy, touchPrivacy, textAndInputPrivacy),
startRecordingImmediately,
replaySampleRate = replaySampleRate,
customEndpoint = "",
privacySettings = SessionReplayPrivacySettings(
imagePrivacyLevel = imagePrivacy,
touchPrivacyLevel = touchPrivacy,
textAndInputPrivacyLevel = textAndInputPrivacy
),
startRecordingImmediately = startRecordingImmediately,
enableHeatmaps = true,
enableCompositionTreeRecording = false,
mockPromise
adaptiveCaptureSchedulingEnabled = false,
promise = mockPromise
)
}

Expand Down
Loading
Loading