From ebef89429cd7a247878b69a5ededa8f01c24a892 Mon Sep 17 00:00:00 2001 From: Marius Constantin Date: Thu, 7 Jul 2022 10:05:00 +0200 Subject: [PATCH 1/2] Move session replay module into library folder --- build.gradle.kts | 33 ++++++++++--------- dd-sdk-android-session-replay/apiSurface | 0 .../transitiveDependencies | 8 ----- dd-sdk-android/build.gradle.kts | 1 + .../dd-sdk-android-session-replay}/.gitignore | 0 .../dd-sdk-android-session-replay}/README.md | 2 +- .../build.gradle.kts | 1 - .../src/main/AndroidManifest.xml | 7 ++-- .../org.mockito.plugins.MockMaker | 0 settings.gradle.kts | 3 +- 10 files changed, 23 insertions(+), 32 deletions(-) delete mode 100644 dd-sdk-android-session-replay/apiSurface delete mode 100644 dd-sdk-android-session-replay/transitiveDependencies rename {dd-sdk-android-session-replay => library/dd-sdk-android-session-replay}/.gitignore (100%) rename {dd-sdk-android-session-replay => library/dd-sdk-android-session-replay}/README.md (67%) rename {dd-sdk-android-session-replay => library/dd-sdk-android-session-replay}/build.gradle.kts (98%) rename {dd-sdk-android-session-replay => library/dd-sdk-android-session-replay}/src/main/AndroidManifest.xml (58%) rename {dd-sdk-android-session-replay => library/dd-sdk-android-session-replay}/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker (100%) diff --git a/build.gradle.kts b/build.gradle.kts index fdd7ee6e86..490d7d1ec1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -76,10 +76,10 @@ tasks.register("assembleAll") { ":dd-sdk-android-ktx:assemble", ":dd-sdk-android-ndk:assemble", ":dd-sdk-android-rx:assemble", - ":dd-sdk-android-session-replay:assemble", ":dd-sdk-android-sqldelight:assemble", ":dd-sdk-android-timber:assemble", - ":dd-sdk-android-tv:assemble" + ":dd-sdk-android-tv:assemble", + ":library:dd-sdk-android-session-replay:assemble" ) } @@ -93,10 +93,10 @@ tasks.register("unitTestRelease") { ":dd-sdk-android-ktx:testReleaseUnitTest", ":dd-sdk-android-ndk:testReleaseUnitTest", ":dd-sdk-android-rx:testReleaseUnitTest", - ":dd-sdk-android-session-replay:testReleaseUnitTest", ":dd-sdk-android-sqldelight:testReleaseUnitTest", ":dd-sdk-android-timber:testReleaseUnitTest", - ":dd-sdk-android-tv:testReleaseUnitTest" + ":dd-sdk-android-tv:testReleaseUnitTest", + ":library:dd-sdk-android-session-replay:testReleaseUnitTest" ) } @@ -110,10 +110,10 @@ tasks.register("unitTestDebug") { ":dd-sdk-android-ktx:testDebugUnitTest", ":dd-sdk-android-ndk:testDebugUnitTest", ":dd-sdk-android-rx:testDebugUnitTest", - ":dd-sdk-android-session-replay:testDebugUnitTest", ":dd-sdk-android-sqldelight:testDebugUnitTest", ":dd-sdk-android-timber:testDebugUnitTest", - ":dd-sdk-android-tv:testDebugUnitTest" + ":dd-sdk-android-tv:testDebugUnitTest", + ":library:dd-sdk-android-session-replay:testDebugUnitTest" ) } @@ -143,12 +143,12 @@ tasks.register("ktlintCheckAll") { ":dd-sdk-android-ktx:ktlintCheck", ":dd-sdk-android-ndk:ktlintCheck", ":dd-sdk-android-rx:ktlintCheck", - ":dd-sdk-android-session-replay:ktlintCheck", ":dd-sdk-android-sqldelight:ktlintCheck", ":dd-sdk-android-timber:ktlintCheck", ":dd-sdk-android-tv:ktlintCheck", ":instrumented:integration:ktlintCheck", ":instrumented:nightly-tests:ktlintCheck", + ":library:dd-sdk-android-session-replay:ktlintCheck", ":tools:detekt:ktlintCheck", ":tools:unit:ktlintCheck" ) @@ -164,10 +164,10 @@ tasks.register("lintCheckAll") { ":dd-sdk-android-ktx:lintRelease", ":dd-sdk-android-ndk:lintRelease", ":dd-sdk-android-rx:lintRelease", - ":dd-sdk-android-session-replay:lintRelease", ":dd-sdk-android-sqldelight:lintRelease", ":dd-sdk-android-timber:lintRelease", - ":dd-sdk-android-tv:lintRelease" + ":dd-sdk-android-tv:lintRelease", + ":library:dd-sdk-android-session-replay:lintRelease" ) } @@ -181,10 +181,10 @@ tasks.register("checkThirdPartyLicensesAll") { ":dd-sdk-android-ktx:checkThirdPartyLicences", ":dd-sdk-android-ndk:checkThirdPartyLicences", ":dd-sdk-android-rx:checkThirdPartyLicences", - ":dd-sdk-android-session-replay:checkThirdPartyLicences", ":dd-sdk-android-sqldelight:checkThirdPartyLicences", ":dd-sdk-android-timber:checkThirdPartyLicences", - ":dd-sdk-android-tv:checkThirdPartyLicences" + ":dd-sdk-android-tv:checkThirdPartyLicences", + ":library:dd-sdk-android-session-replay:checkThirdPartyLicences" ) } @@ -198,10 +198,10 @@ tasks.register("checkApiSurfaceChangesAll") { ":dd-sdk-android-ktx:checkApiSurfaceChanges", ":dd-sdk-android-ndk:checkApiSurfaceChanges", ":dd-sdk-android-rx:checkApiSurfaceChanges", - ":dd-sdk-android-session-replay:checkApiSurfaceChanges", ":dd-sdk-android-sqldelight:checkApiSurfaceChanges", ":dd-sdk-android-timber:checkApiSurfaceChanges", - ":dd-sdk-android-tv:checkApiSurfaceChanges" + ":dd-sdk-android-tv:checkApiSurfaceChanges", + ":library:dd-sdk-android-session-replay:checkApiSurfaceChanges" ) } @@ -216,11 +216,11 @@ tasks.register("detektAll") { ":dd-sdk-android-ndk:detektMain", ":dd-sdk-android-rx:detektMain", ":dd-sdk-android-sqldelight:detektMain", - ":dd-sdk-android-session-replay:detektMain", ":dd-sdk-android-timber:detektMain", ":dd-sdk-android-tv:detektMain", ":instrumented:integration:detekt", ":instrumented:nightly-tests:detekt", + ":library:dd-sdk-android-session-replay:detektMain", ":tools:unit:detekt" ) } @@ -238,8 +238,9 @@ tasks.register("koverReportAll") { ":dd-sdk-android-session-replay:koverXmlReport", ":dd-sdk-android-sqldelight:koverXmlReport", ":dd-sdk-android-timber:koverXmlReport", - ":dd-sdk-android-tv:koverXmlReport" - ) + ":dd-sdk-android-tv:koverXmlReport", + ":library:dd-sdk-android-session-replay:koverXmlReport", + ) } tasks.register("instrumentTestAll") { diff --git a/dd-sdk-android-session-replay/apiSurface b/dd-sdk-android-session-replay/apiSurface deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/dd-sdk-android-session-replay/transitiveDependencies b/dd-sdk-android-session-replay/transitiveDependencies deleted file mode 100644 index a8e93c8d38..0000000000 --- a/dd-sdk-android-session-replay/transitiveDependencies +++ /dev/null @@ -1,8 +0,0 @@ -Dependencies List - -org.jetbrains.kotlin:kotlin-stdlib-common:1.6.10 : 195 Kb -org.jetbrains.kotlin:kotlin-stdlib:1.6.10 : 1472 Kb -org.jetbrains:annotations:13.0 : 17 Kb - -Total transitive dependencies size : 1685 Kb - diff --git a/dd-sdk-android/build.gradle.kts b/dd-sdk-android/build.gradle.kts index da820cf998..32185ade75 100644 --- a/dd-sdk-android/build.gradle.kts +++ b/dd-sdk-android/build.gradle.kts @@ -124,6 +124,7 @@ android { } dependencies { + api(project(":library:dd-sdk-android-session-replay")) implementation(libs.kotlin) // Network diff --git a/dd-sdk-android-session-replay/.gitignore b/library/dd-sdk-android-session-replay/.gitignore similarity index 100% rename from dd-sdk-android-session-replay/.gitignore rename to library/dd-sdk-android-session-replay/.gitignore diff --git a/dd-sdk-android-session-replay/README.md b/library/dd-sdk-android-session-replay/README.md similarity index 67% rename from dd-sdk-android-session-replay/README.md rename to library/dd-sdk-android-session-replay/README.md index ab63f276a2..af0a477bd0 100644 --- a/dd-sdk-android-session-replay/README.md +++ b/library/dd-sdk-android-session-replay/README.md @@ -1,3 +1,3 @@ # Datadog Integration for Session Replay -## Getting Started +## Getting Started \ No newline at end of file diff --git a/dd-sdk-android-session-replay/build.gradle.kts b/library/dd-sdk-android-session-replay/build.gradle.kts similarity index 98% rename from dd-sdk-android-session-replay/build.gradle.kts rename to library/dd-sdk-android-session-replay/build.gradle.kts index 9a5e5a81b4..6260f27935 100644 --- a/dd-sdk-android-session-replay/build.gradle.kts +++ b/library/dd-sdk-android-session-replay/build.gradle.kts @@ -74,7 +74,6 @@ android { } dependencies { - api(project(":dd-sdk-android")) implementation(libs.kotlin) testImplementation(project(":tools:unit")) diff --git a/dd-sdk-android-session-replay/src/main/AndroidManifest.xml b/library/dd-sdk-android-session-replay/src/main/AndroidManifest.xml similarity index 58% rename from dd-sdk-android-session-replay/src/main/AndroidManifest.xml rename to library/dd-sdk-android-session-replay/src/main/AndroidManifest.xml index f161db41b1..ec07c04b20 100644 --- a/dd-sdk-android-session-replay/src/main/AndroidManifest.xml +++ b/library/dd-sdk-android-session-replay/src/main/AndroidManifest.xml @@ -1,12 +1,9 @@ - - - - + diff --git a/dd-sdk-android-session-replay/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/library/dd-sdk-android-session-replay/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from dd-sdk-android-session-replay/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to library/dd-sdk-android-session-replay/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/settings.gradle.kts b/settings.gradle.kts index ef9a2deccb..1de7cf5834 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,7 +14,6 @@ include(":dd-sdk-android-glide") include(":dd-sdk-android-ktx") include(":dd-sdk-android-ndk") include(":dd-sdk-android-rx") -include(":dd-sdk-android-session-replay") include(":dd-sdk-android-sqldelight") include(":dd-sdk-android-timber") include(":dd-sdk-android-tv") @@ -22,6 +21,8 @@ include(":dd-sdk-android-tv") include(":instrumented:integration") include(":instrumented:nightly-tests") +include(":library:dd-sdk-android-session-replay") + include(":sample:kotlin") include(":tools:detekt") From 97761af4594311c3da89209e5bac3fb359fbe7c4 Mon Sep 17 00:00:00 2001 From: Marius Constantin Date: Thu, 7 Jul 2022 12:35:22 +0200 Subject: [PATCH 2/2] Add the Session Replay Public API --- dd-sdk-android/apiSurface | 7 +- dd-sdk-android/build.gradle.kts | 1 + .../com/datadog/android/DatadogEndpoint.kt | 36 ++++++++++ .../core/configuration/Configuration.kt | 20 +++++- .../com/datadog/android/plugin/Feature.kt | 3 +- .../internal/SessionReplayFeature.kt | 43 ++++++++++++ .../internal/domain/RecordSerializer.kt | 17 +++++ .../SessionReplayRecordPersistenceStrategy.kt | 41 ++++++++++++ .../datadog/android/v2/core/DatadogCore.kt | 13 ++++ .../configuration/ConfigurationBuilderTest.kt | 66 ++++++++++++------- .../dd-sdk-android-session-replay/apiSurface | 0 .../transitiveDependencies | 8 +++ 12 files changed, 230 insertions(+), 25 deletions(-) create mode 100644 dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/SessionReplayFeature.kt create mode 100644 dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/RecordSerializer.kt create mode 100644 dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/SessionReplayRecordPersistenceStrategy.kt create mode 100644 library/dd-sdk-android-session-replay/apiSurface create mode 100644 library/dd-sdk-android-session-replay/transitiveDependencies diff --git a/dd-sdk-android/apiSurface b/dd-sdk-android/apiSurface index 224d11460b..1416d6af55 100644 --- a/dd-sdk-android/apiSurface +++ b/dd-sdk-android/apiSurface @@ -35,6 +35,10 @@ object com.datadog.android.DatadogEndpoint const val NTP_1: String const val NTP_2: String const val NTP_3: String + const val SESSION_REPLAY_US1: String + const val SESSION_REPLAY_US3: String + const val SESSION_REPLAY_US5: String + const val SESSION_REPLAY_EU1: String class com.datadog.android.DatadogEventListener : okhttp3.EventListener override fun callStart(okhttp3.Call) override fun dnsStart(okhttp3.Call, String) @@ -74,7 +78,7 @@ enum com.datadog.android.core.configuration.BatchSize - LARGE data class com.datadog.android.core.configuration.Configuration class Builder - constructor(Boolean, Boolean, Boolean, Boolean) + constructor(Boolean, Boolean, Boolean, Boolean, Boolean) fun build(): Configuration fun setUseDeveloperModeWhenDebuggable(Boolean): Builder fun setFirstPartyHosts(List): Builder @@ -295,6 +299,7 @@ enum com.datadog.android.plugin.Feature - CRASH - TRACE - RUM + - SESSION_REPLAY enum com.datadog.android.privacy.TrackingConsent - GRANTED - NOT_GRANTED diff --git a/dd-sdk-android/build.gradle.kts b/dd-sdk-android/build.gradle.kts index 32185ade75..25e093eab4 100644 --- a/dd-sdk-android/build.gradle.kts +++ b/dd-sdk-android/build.gradle.kts @@ -124,6 +124,7 @@ android { } dependencies { + // TODO Invert the Dependency Once SDKCore is ready. RUMM-2338 api(project(":library:dd-sdk-android-session-replay")) implementation(libs.kotlin) diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogEndpoint.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogEndpoint.kt index a257b29554..c0c69ef4c9 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogEndpoint.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/DatadogEndpoint.kt @@ -241,4 +241,40 @@ object DatadogEndpoint { const val NTP_3: String = "3.datadog.pool.ntp.org" // endregion + + // region Session Replay + + /** + * The US1 endpoint for Session Replay (US based servers). + * Use this in your [Configuration] if you want to point to + * [app.datadoghq.com](https://app.datadoghq.com) + * @see [Configuration] + */ + const val SESSION_REPLAY_US1: String = "https://session-replay.browser-intake-datadoghq.com" + + /** + * The US3 endpoint for Session Replay (US based servers). + * Use this in your [Configuration] if you want to point to + * [us3.datadoghq.com](https://us3.datadoghq.com) + * @see [Configuration] + */ + const val SESSION_REPLAY_US3: String = "https://session-replay.browser-intake-us3-datadoghq.com" + + /** + * The US5 endpoint for Session replay (US based servers). + * Use this in your [Configuration] if you want to point to + * [us5.datadoghq.com](https://us5.datadoghq.com) + * @see [Configuration] + */ + const val SESSION_REPLAY_US5: String = "https://session-replay.browser-intake-us5-datadoghq.com" + + /** + * The EU1 endpoint for Session Replay (EU based servers). + * Use this in your [Configuration] if you want to point to + * [app.datadoghq.eu](https://app.datadoghq.eu) + * @see [Configuration] + */ + const val SESSION_REPLAY_EU1: String = "https://session-replay.browser-intake-datadoghq.eu" + + // endregion } diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt index b96dea5bc1..9b40948e67 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/core/configuration/Configuration.kt @@ -60,6 +60,7 @@ internal constructor( internal val tracesConfig: Feature.Tracing?, internal val crashReportConfig: Feature.CrashReport?, internal val rumConfig: Feature.RUM?, + internal val sessionReplayConfig: Feature.SessionReplay?, internal val additionalConfig: Map ) { @@ -107,6 +108,11 @@ internal constructor( val rumEventMapper: EventMapper, val backgroundEventTracking: Boolean ) : Feature() + + internal data class SessionReplay( + override val endpointUrl: String, + override val plugins: List + ) : Feature() } // region Builder @@ -117,18 +123,21 @@ internal constructor( * @param tracesEnabled whether Spans are tracked and sent to Datadog * @param crashReportsEnabled whether crashes are tracked and sent to Datadog * @param rumEnabled whether RUM events are tracked and sent to Datadog + * @param sessionReplayEnabled whether RUM Session Replay is enabled or not */ @Suppress("TooManyFunctions") class Builder( val logsEnabled: Boolean, val tracesEnabled: Boolean, val crashReportsEnabled: Boolean, - val rumEnabled: Boolean + val rumEnabled: Boolean, + val sessionReplayEnabled: Boolean ) { private var logsConfig: Feature.Logs = DEFAULT_LOGS_CONFIG private var tracesConfig: Feature.Tracing = DEFAULT_TRACING_CONFIG private var crashReportConfig: Feature.CrashReport = DEFAULT_CRASH_CONFIG private var rumConfig: Feature.RUM = DEFAULT_RUM_CONFIG + private var sessionReplayConfig: Feature.SessionReplay = DEFAULT_SESSION_REPLAY_CONFIG private var additionalConfig: Map = emptyMap() private var coreConfig = DEFAULT_CORE_CONFIG @@ -145,6 +154,7 @@ internal constructor( tracesConfig = if (tracesEnabled) tracesConfig else null, crashReportConfig = if (crashReportsEnabled) crashReportConfig else null, rumConfig = if (rumEnabled) rumConfig else null, + sessionReplayConfig = if (sessionReplayEnabled) sessionReplayConfig else null, additionalConfig = additionalConfig ) } @@ -431,6 +441,9 @@ internal constructor( PluginFeature.CRASH -> crashReportConfig = crashReportConfig.copy( plugins = crashReportConfig.plugins + plugin ) + PluginFeature.SESSION_REPLAY -> + sessionReplayConfig = + sessionReplayConfig.copy(plugins = sessionReplayConfig.plugins + plugin) } } return this @@ -684,6 +697,7 @@ internal constructor( PluginFeature.TRACE -> tracesEnabled PluginFeature.CRASH -> crashReportsEnabled PluginFeature.RUM -> rumEnabled + PluginFeature.SESSION_REPLAY -> sessionReplayEnabled } if (featureEnabled) { @Suppress("UnsafeThirdPartyFunctionCall") // internal safe call @@ -740,6 +754,10 @@ internal constructor( rumEventMapper = NoOpEventMapper(), backgroundEventTracking = false ) + internal val DEFAULT_SESSION_REPLAY_CONFIG = Feature.SessionReplay( + endpointUrl = DatadogEndpoint.SESSION_REPLAY_US1, + plugins = emptyList() + ) internal const val ERROR_FEATURE_DISABLED = "The %s feature has been disabled in your " + "Configuration.Builder, but you're trying to edit the RUM configuration with the " + diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/plugin/Feature.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/plugin/Feature.kt index 23f0863c90..e196771eb9 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/plugin/Feature.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/plugin/Feature.kt @@ -13,5 +13,6 @@ enum class Feature(internal val featureName: String) { LOG("Logging"), CRASH("Crash Reporting"), TRACE("Tracing"), - RUM("RUM") + RUM("RUM"), + SESSION_REPLAY("Session Replay") } diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/SessionReplayFeature.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/SessionReplayFeature.kt new file mode 100644 index 0000000000..a4f82613f5 --- /dev/null +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/SessionReplayFeature.kt @@ -0,0 +1,43 @@ +/* + * 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 + +import android.content.Context +import com.datadog.android.core.configuration.Configuration +import com.datadog.android.core.internal.CoreFeature +import com.datadog.android.core.internal.SdkFeature +import com.datadog.android.core.internal.net.DataUploader +import com.datadog.android.core.internal.net.NoOpDataUploader +import com.datadog.android.core.internal.persistence.PersistenceStrategy +import com.datadog.android.core.internal.utils.sdkLogger +import com.datadog.android.sessionreplay.internal.domain.SessionReplayRecordPersistenceStrategy + +internal class SessionReplayFeature(coreFeature: CoreFeature) : + SdkFeature(coreFeature) { + + override fun createPersistenceStrategy( + context: Context, + configuration: Configuration.Feature.SessionReplay + ): PersistenceStrategy { + return SessionReplayRecordPersistenceStrategy( + coreFeature.trackingConsentProvider, + context, + coreFeature.persistenceExecutorService, + sdkLogger, + coreFeature.localDataEncryption + ) + } + + override fun createUploader(configuration: Configuration.Feature.SessionReplay): DataUploader { + // TODO: This will be added later in RUMM-2273 + return NoOpDataUploader() + } + + companion object { + const val SESSION_REPLAY_FEATURE_NAME = "session-replay" + } +} diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/RecordSerializer.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/RecordSerializer.kt new file mode 100644 index 0000000000..dbfde519af --- /dev/null +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/RecordSerializer.kt @@ -0,0 +1,17 @@ +/* + * 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.domain + +import com.datadog.android.core.internal.persistence.Serializer + +internal class RecordSerializer : Serializer { + override fun serialize(model: Any): String? { + // TODO: This will be switched to a Serializer once the models + // will be in place. RUMM-2330" + return null + } +} diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/SessionReplayRecordPersistenceStrategy.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/SessionReplayRecordPersistenceStrategy.kt new file mode 100644 index 0000000000..5b3fce5ca1 --- /dev/null +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/sessionreplay/internal/domain/SessionReplayRecordPersistenceStrategy.kt @@ -0,0 +1,41 @@ +/* + * 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.domain + +import android.content.Context +import com.datadog.android.core.internal.persistence.PayloadDecoration +import com.datadog.android.core.internal.persistence.file.FileMover +import com.datadog.android.core.internal.persistence.file.advanced.FeatureFileOrchestrator +import com.datadog.android.core.internal.persistence.file.batch.BatchFilePersistenceStrategy +import com.datadog.android.core.internal.persistence.file.batch.BatchFileReaderWriter +import com.datadog.android.core.internal.privacy.ConsentProvider +import com.datadog.android.log.Logger +import com.datadog.android.security.Encryption +import com.datadog.android.sessionreplay.internal.SessionReplayFeature +import java.util.concurrent.ExecutorService + +internal class SessionReplayRecordPersistenceStrategy( + consentProvider: ConsentProvider, + context: Context, + executorService: ExecutorService, + internalLogger: Logger, + localDataEncryption: Encryption? +) : BatchFilePersistenceStrategy( + FeatureFileOrchestrator( + consentProvider, + context, + SessionReplayFeature.SESSION_REPLAY_FEATURE_NAME, + executorService, + internalLogger + ), + executorService, + RecordSerializer(), + PayloadDecoration.NEW_LINE_DECORATION, + internalLogger, + BatchFileReaderWriter.create(internalLogger, localDataEncryption), + FileMover(internalLogger) +) diff --git a/dd-sdk-android/src/main/kotlin/com/datadog/android/v2/core/DatadogCore.kt b/dd-sdk-android/src/main/kotlin/com/datadog/android/v2/core/DatadogCore.kt index e0ec00e3f6..3116dfface 100644 --- a/dd-sdk-android/src/main/kotlin/com/datadog/android/v2/core/DatadogCore.kt +++ b/dd-sdk-android/src/main/kotlin/com/datadog/android/v2/core/DatadogCore.kt @@ -28,6 +28,7 @@ import com.datadog.android.log.internal.LogsFeature import com.datadog.android.log.model.LogEvent import com.datadog.android.privacy.TrackingConsent import com.datadog.android.rum.internal.RumFeature +import com.datadog.android.sessionreplay.internal.SessionReplayFeature import com.datadog.android.tracing.internal.TracingFeature import com.datadog.android.v2.api.FeatureScope import com.datadog.android.v2.api.FeatureStorageConfiguration @@ -60,6 +61,7 @@ class DatadogCore( null internal var webViewLogsFeature: SdkFeature? = null internal var webViewRumFeature: SdkFeature? = null + internal var sessionReplayFeature: SdkFeature? = null init { val isDebug = isAppDebuggable(context) @@ -176,6 +178,7 @@ class DatadogCore( initializeTracingFeature(mutableConfig.tracesConfig, appContext) initializeRumFeature(mutableConfig.rumConfig, appContext) initializeCrashReportFeature(mutableConfig.crashReportConfig, appContext) + initializeSessionReplayFeature(mutableConfig.sessionReplayConfig, appContext) coreFeature.ndkCrashHandler.handleNdkCrash( logsFeature?.persistenceStrategy?.getWriter() ?: NoOpDataWriter(), @@ -252,6 +255,16 @@ class DatadogCore( } } + private fun initializeSessionReplayFeature( + configuration: Configuration.Feature.SessionReplay?, + appContext: Context + ) { + if (configuration != null) { + sessionReplayFeature = SessionReplayFeature(coreFeature) + sessionReplayFeature?.initialize(appContext, configuration) + } + } + @Suppress("FunctionMaxLength") private fun modifyConfigurationForDeveloperDebug(configuration: Configuration): Configuration { return configuration.copy( diff --git a/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt b/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt index dcca3ffc90..273ffdae6b 100644 --- a/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt +++ b/dd-sdk-android/src/test/kotlin/com/datadog/android/core/configuration/ConfigurationBuilderTest.kt @@ -85,7 +85,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) } @@ -161,7 +162,8 @@ internal class ConfigurationBuilderTest { logsEnabled = false, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) // When @@ -182,7 +184,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = false, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) // When @@ -203,7 +206,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = false, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) // When @@ -224,7 +228,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) // When @@ -814,7 +819,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) // When @@ -840,7 +846,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) // When @@ -864,7 +871,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val viewStrategy: ViewTrackingStrategy = mock() @@ -891,7 +899,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) // When @@ -915,7 +924,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val eventMapper: ViewEventMapper = mock() @@ -940,7 +950,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val eventMapper: EventMapper = mock() @@ -965,7 +976,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val eventMapper: EventMapper = mock() @@ -990,7 +1002,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val eventMapper: EventMapper = mock() @@ -1015,7 +1028,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val eventMapper: EventMapper = mock() @@ -1040,7 +1054,8 @@ internal class ConfigurationBuilderTest { logsEnabled = false, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) val logsPlugin: DatadogPlugin = mock() @@ -1065,7 +1080,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = false, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) val tracesPlugin: DatadogPlugin = mock() @@ -1090,7 +1106,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = false, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) val crashPlugin: DatadogPlugin = mock() @@ -1115,7 +1132,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) val rumPlugin: DatadogPlugin = mock() @@ -1142,7 +1160,8 @@ internal class ConfigurationBuilderTest { logsEnabled = false, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) // When @@ -1168,7 +1187,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = false, crashReportsEnabled = true, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) // When @@ -1194,7 +1214,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = false, - rumEnabled = true + rumEnabled = true, + sessionReplayEnabled = true ) // When @@ -1220,7 +1241,8 @@ internal class ConfigurationBuilderTest { logsEnabled = true, tracesEnabled = true, crashReportsEnabled = true, - rumEnabled = false + rumEnabled = false, + sessionReplayEnabled = true ) // When diff --git a/library/dd-sdk-android-session-replay/apiSurface b/library/dd-sdk-android-session-replay/apiSurface new file mode 100644 index 0000000000..e69de29bb2 diff --git a/library/dd-sdk-android-session-replay/transitiveDependencies b/library/dd-sdk-android-session-replay/transitiveDependencies new file mode 100644 index 0000000000..a8e93c8d38 --- /dev/null +++ b/library/dd-sdk-android-session-replay/transitiveDependencies @@ -0,0 +1,8 @@ +Dependencies List + +org.jetbrains.kotlin:kotlin-stdlib-common:1.6.10 : 195 Kb +org.jetbrains.kotlin:kotlin-stdlib:1.6.10 : 1472 Kb +org.jetbrains:annotations:13.0 : 17 Kb + +Total transitive dependencies size : 1685 Kb +