From a90a51b8065dc90cb021f58a06893ed505b641f8 Mon Sep 17 00:00:00 2001 From: Timur Valeev Date: Fri, 14 Aug 2026 12:06:27 +0100 Subject: [PATCH 1/4] RUM-17613 Rename Timeseries abstractions to TimeseriesCollector Rename the internal Timeseries interface to TimeseriesCollector and rename its implementations to DefaultTimeseriesCollector and DefaultTimeseriesCollectorFactory, propagating the new names through RumFeature, the RUM scope tree and the tests. No behaviour change. Ref: RUM-17613 --- detekt_custom_safe_calls_third_party.yml | 6 +- .../kotlin/com/datadog/android/rum/Rum.kt | 2 +- .../android/rum/internal/RumFeature.kt | 16 +-- .../domain/scope/RumApplicationScope.kt | 8 +- .../internal/domain/scope/RumSessionScope.kt | 20 +-- .../rum/internal/monitor/DatadogRumMonitor.kt | 8 +- ...eries.kt => DefaultTimeseriesCollector.kt} | 4 +- ...t => DefaultTimeseriesCollectorFactory.kt} | 6 +- .../{Timeseries.kt => TimeseriesCollector.kt} | 4 +- .../android/rum/internal/RumFeatureTest.kt | 12 +- ...pplicationScopeAttributePropagationTest.kt | 10 +- .../domain/scope/RumApplicationScopeTest.kt | 14 +- ...RumSessionScopeAttributePropagationTest.kt | 10 +- .../domain/scope/RumSessionScopeTest.kt | 132 +++++++++--------- .../internal/monitor/DatadogRumMonitorTest.kt | 35 +++-- ... DefaultTimeseriesCollectorFactoryTest.kt} | 8 +- ...t.kt => DefaultTimeseriesCollectorTest.kt} | 20 +-- .../csv/{CsvTimeseries.kt => CsvCollector.kt} | 12 +- ....kt => TimeseriesCollectorEndToEndTest.kt} | 4 +- .../VitalReaderWrapperTest.kt} | 5 +- 20 files changed, 176 insertions(+), 160 deletions(-) rename features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/{RumSessionScopeTimeseries.kt => DefaultTimeseriesCollector.kt} (98%) rename features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/{RumSessionScopeTimeseriesFactory.kt => DefaultTimeseriesCollectorFactory.kt} (90%) rename features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/{Timeseries.kt => TimeseriesCollector.kt} (89%) rename features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/{RumSessionScopeTimeseriesFactoryTest.kt => DefaultTimeseriesCollectorFactoryTest.kt} (93%) rename features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/{RumSessionScopeTimeseriesTest.kt => DefaultTimeseriesCollectorTest.kt} (97%) rename features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/{CsvTimeseries.kt => CsvCollector.kt} (91%) rename features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/{TimeseriesEndToEndTest.kt => TimeseriesCollectorEndToEndTest.kt} (99%) rename features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/{VitalReaderDataPointsReaderTest.kt => provider/VitalReaderWrapperTest.kt} (94%) diff --git a/detekt_custom_safe_calls_third_party.yml b/detekt_custom_safe_calls_third_party.yml index b44f9ddebc..9f3686b425 100644 --- a/detekt_custom_safe_calls_third_party.yml +++ b/detekt_custom_safe_calls_third_party.yml @@ -259,7 +259,7 @@ datadog: - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.api.SdkCore?, com.datadog.android.api.SdkCore?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.flags.internal.repository.DefaultFlagsRepository.FlagsState?, com.datadog.android.flags.internal.repository.DefaultFlagsRepository.FlagsState?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.trace.bootstrap.instrumentation.api.AgentTracer.TracerAPI?, com.datadog.trace.bootstrap.instrumentation.api.AgentTracer.TracerAPI?)" - - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseries.State?, com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseries.State?)" + - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?, com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.trace.api.tracer.DatadogTracer?, com.datadog.android.trace.api.tracer.DatadogTracer?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(kotlin.String?, kotlin.String?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(kotlin.collections.Set?, kotlin.collections.Set?)" @@ -272,14 +272,14 @@ datadog: - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.flags.model.FlagsClientState?)" - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.flags.model.ProviderContext?)" - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.rum.internal.domain.RumContext?)" - - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseries.State?)" + - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?)" - "java.util.concurrent.atomic.AtomicReference.constructor(kotlin.collections.Map?)" - "java.util.concurrent.atomic.AtomicReference.constructor(kotlin.String?)" - "java.util.concurrent.atomic.AtomicReference.constructor(kotlin.collections.Set?)" - "java.util.concurrent.atomic.AtomicReference.get()" - "java.util.concurrent.atomic.AtomicReference.getAndSet(kotlin.String?)" - "java.util.concurrent.atomic.AtomicReference.getAndSet(java.util.concurrent.Future?)" - - "java.util.concurrent.atomic.AtomicReference.getAndSet(com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseries.State?)" + - "java.util.concurrent.atomic.AtomicReference.getAndSet(com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?)" - "java.util.concurrent.atomic.AtomicReference.set(android.app.Application.ActivityLifecycleCallbacks?)" - "java.util.concurrent.atomic.AtomicReference.set(com.datadog.android.api.FeatureEventReceiver?)" - "java.util.concurrent.atomic.AtomicReference.set(com.datadog.android.api.SdkCore?)" diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt index 56eba4f318..80ffa3b0aa 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt @@ -167,7 +167,7 @@ object Rum { }, insightsCollector = rumFeature.insightsCollector, heatmapIdentifierRegistry = rumFeature.heatmapIdentifierRegistry, - timeseriesFactory = rumFeature.timeseriesFactory + timeseriesCollectorFactory = rumFeature.timeseriesCollectorFactory ) } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt index 8c995b90e6..89c48906c6 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt @@ -92,10 +92,10 @@ import com.datadog.android.rum.internal.startup.RumStartupScenario import com.datadog.android.rum.internal.startup.RumTTIDInfo import com.datadog.android.rum.internal.thread.NoOpScheduledExecutorService import com.datadog.android.rum.internal.timeseries.Buffer -import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesFactory +import com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollectorFactory +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory import com.datadog.android.rum.internal.timeseries.Pipeline -import com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseriesFactory -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.timeseries.provider.CpuDatapointReader import com.datadog.android.rum.internal.timeseries.provider.VitalReaderWrapper import com.datadog.android.rum.internal.timeseries.serializer.CpuEventSerializer @@ -200,7 +200,7 @@ internal class RumFeature( internal val rumContextUpdateReceivers = mutableSetOf() internal var insightsCollector: InsightsCollector = NoOpInsightsCollector() override val heatmapIdentifierRegistry: HeatmapIdentifierRegistry = HeatmapIdentifierRegistry.create() - internal var timeseriesFactory: Timeseries.Factory = NoOpTimeseriesFactory() + internal var timeseriesCollectorFactory: TimeseriesCollector.Factory = NoOpTimeseriesCollectorFactory() private val lateCrashEventHandler by lazy { lateCrashReporterFactory(sdkCore as InternalSdkCore) } internal var rumAppStartupDetector: RumAppStartupDetector? = null @@ -303,7 +303,7 @@ internal class RumFeature( sessionListener = configuration.sessionListener configuration.timeseriesConfiguration?.let { configuration -> - timeseriesFactory = createTimeseriesCollectingFactory( + timeseriesCollectorFactory = createTimeseriesCollectingFactory( configuration, appContext.readTotalRamBytes(sdkCore.internalLogger) ?: 0L, insightsCollector @@ -375,8 +375,8 @@ internal class RumFeature( unregisterTrackingStrategies(appContext) - timeseriesFactory = NoOpTimeseriesFactory() - (GlobalRumMonitor.get(sdkCore) as? DatadogRumMonitor)?.stopActiveTimeseries() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() + (GlobalRumMonitor.get(sdkCore) as? DatadogRumMonitor)?.stopTimeseries() dataWriter = NoOpDataWriter() @@ -457,7 +457,7 @@ internal class RumFeature( configuration: TimeseriesConfiguration, totalRamBytes: Long, insightsCollector: InsightsCollector - ): Timeseries.Factory = RumSessionScopeTimeseriesFactory( + ): TimeseriesCollector.Factory = DefaultTimeseriesCollectorFactory( internalLogger = sdkCore.internalLogger, collectInBackground = configuration.collectInBackground, scheduledExecutorService = vitalExecutorService, diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScope.kt index daeb20280a..07aba22a7d 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScope.kt @@ -30,7 +30,7 @@ import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollect import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.startup.RumSessionScopeStartupManager -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -59,7 +59,7 @@ internal class RumApplicationScope( private val rumSessionScopeStartupManagerFactory: () -> RumSessionScopeStartupManager, private val insightsCollector: InsightsCollector, private val heatmapIdentifierRegistry: HeatmapIdentifierRegistry?, - private val timeseriesFactory: Timeseries.Factory + private val timeseriesCollectorFactory: TimeseriesCollector.Factory ) : RumScope, RumViewChangedListener { override val parentScope: RumScope? = null @@ -91,7 +91,7 @@ internal class RumApplicationScope( rumSessionScopeStartupManagerFactory = rumSessionScopeStartupManagerFactory, insightsCollector = insightsCollector, heatmapIdentifierRegistry = heatmapIdentifierRegistry, - timeseriesFactory = timeseriesFactory + timeseriesCollectorFactory = timeseriesCollectorFactory ) ) @@ -215,7 +215,7 @@ internal class RumApplicationScope( rumSessionScopeStartupManagerFactory = rumSessionScopeStartupManagerFactory, insightsCollector = insightsCollector, heatmapIdentifierRegistry = heatmapIdentifierRegistry, - timeseriesFactory = timeseriesFactory + timeseriesCollectorFactory = timeseriesCollectorFactory ) childScopes.add(newSession) if (event !is RumRawEvent.StartView) { diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt index 8d5396e559..618f28c7db 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt @@ -28,9 +28,9 @@ import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollect import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.startup.RumSessionScopeStartupManager -import com.datadog.android.rum.internal.timeseries.NoOpTimeseries -import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesFactory -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollector +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -65,10 +65,10 @@ internal class RumSessionScope( private val rumSessionScopeStartupManagerFactory: () -> RumSessionScopeStartupManager, insightsCollector: InsightsCollector, heatmapIdentifierRegistry: HeatmapIdentifierRegistry?, - private val timeseriesFactory: Timeseries.Factory = NoOpTimeseriesFactory() + private val timeseriesCollectorFactory: TimeseriesCollector.Factory = NoOpTimeseriesCollectorFactory() ) : RumScope { - private var timeseries: Timeseries = NoOpTimeseries() + private var timeseriesCollector: TimeseriesCollector = NoOpTimeseriesCollector() internal var sessionId = RumContext.NULL_UUID internal var sessionState: State = State.NOT_TRACKED @@ -201,7 +201,7 @@ internal class RumSessionScope( } } - timeseries.onViewTypeUpdate(getActiveRumContext().viewType) + timeseriesCollector.onViewTypeUpdate(getActiveRumContext().viewType) return if (isSessionComplete()) { null @@ -234,17 +234,17 @@ internal class RumSessionScope( } private fun startTimeseries() { - timeseries = timeseriesFactory.create( + timeseriesCollector = timeseriesCollectorFactory.create( sessionId = sessionId, applicationId = parentScope.getRumContext().applicationId, sessionType = getRumContext().resolveSessionType(rumSessionTypeOverride) ) - timeseries.onSessionStart() + timeseriesCollector.onSessionStart() } internal fun stopTimeseries() { - timeseries.onSessionStop() - timeseries = NoOpTimeseries() + timeseriesCollector.onSessionStop() + timeseriesCollector = NoOpTimeseriesCollector() } private fun stopSession() { diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt index e73a358cca..c2c834a073 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt @@ -66,7 +66,7 @@ import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.startup.RumSessionScopeStartupManager import com.datadog.android.rum.internal.startup.RumStartupScenario import com.datadog.android.rum.internal.startup.RumTTIDInfo -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -111,7 +111,7 @@ internal class DatadogRumMonitor( private val rumSessionScopeStartupManagerFactory: () -> RumSessionScopeStartupManager, insightsCollector: InsightsCollector, heatmapIdentifierRegistry: HeatmapIdentifierRegistry?, - timeseriesFactory: Timeseries.Factory + timeseriesCollectorFactory: TimeseriesCollector.Factory ) : RumMonitor, AdvancedRumMonitor { @Volatile private var cachedViewUrl: String? = null @@ -138,7 +138,7 @@ internal class DatadogRumMonitor( rumSessionScopeStartupManagerFactory = rumSessionScopeStartupManagerFactory, insightsCollector = insightsCollector, heatmapIdentifierRegistry = heatmapIdentifierRegistry, - timeseriesFactory = timeseriesFactory + timeseriesCollectorFactory = timeseriesCollectorFactory ) internal var debugListener: RumDebugListener? = null @@ -935,7 +935,7 @@ internal class DatadogRumMonitor( * de-initializes and shuts down its context executor before the async write task fires, the * write is silently skipped regardless. */ - internal fun stopActiveTimeseries() { + internal fun stopTimeseries() { synchronized(rootScope) { rootScope.activeSession?.stopTimeseries() } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseries.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt similarity index 98% rename from features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseries.kt rename to features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt index 1fc4a36d92..506506ac77 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseries.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt @@ -36,12 +36,12 @@ import java.util.concurrent.atomic.AtomicReference * When [startSampling] starts a new generation, any in-flight or queued ticks from the * previous generation self-terminate on their first check. */ -internal class RumSessionScopeTimeseries( +internal class DefaultTimeseriesCollector( private val internalLogger: InternalLogger, internal val pipelines: List>, private val collectInBackground: Boolean, internal val scheduledExecutorService: ScheduledExecutorService -) : Timeseries { +) : TimeseriesCollector { private enum class State { IDLE, RUNNING, SUSPENDED, STOPPED } private val state = AtomicReference(State.IDLE) diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactory.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt similarity index 90% rename from features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactory.kt rename to features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt index 9e42560294..bec629e64e 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactory.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt @@ -10,7 +10,7 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.rum.RumSessionType import java.util.concurrent.ScheduledExecutorService -internal class RumSessionScopeTimeseriesFactory( +internal class DefaultTimeseriesCollectorFactory( private val internalLogger: InternalLogger, private val collectInBackground: Boolean, private val scheduledExecutorService: ScheduledExecutorService, @@ -19,10 +19,10 @@ internal class RumSessionScopeTimeseriesFactory( sessionId: String, sessionType: RumSessionType ) -> List> -) : Timeseries.Factory { +) : TimeseriesCollector.Factory { override fun create(applicationId: String, sessionId: String, sessionType: RumSessionType) = - RumSessionScopeTimeseries( + DefaultTimeseriesCollector( internalLogger = internalLogger, collectInBackground = collectInBackground, scheduledExecutorService = scheduledExecutorService, diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Timeseries.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt similarity index 89% rename from features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Timeseries.kt rename to features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt index f08f5144fe..93fc71ec3f 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Timeseries.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt @@ -11,13 +11,13 @@ import com.datadog.android.rum.internal.domain.scope.RumViewType import com.datadog.tools.annotation.NoOpImplementation @NoOpImplementation -internal interface Timeseries { +internal interface TimeseriesCollector { fun onSessionStart() fun onSessionStop() fun onViewTypeUpdate(newViewType: RumViewType) @NoOpImplementation interface Factory { - fun create(applicationId: String, sessionId: String, sessionType: RumSessionType): Timeseries + fun create(applicationId: String, sessionId: String, sessionType: RumSessionType): TimeseriesCollector } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt index 3778de151e..bb3139225d 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt @@ -56,8 +56,8 @@ import com.datadog.android.rum.internal.monitor.DatadogRumMonitor import com.datadog.android.rum.internal.monitor.NoOpAdvancedRumMonitor import com.datadog.android.rum.internal.startup.RumAppStartupDetector import com.datadog.android.rum.internal.thread.NoOpScheduledExecutorService -import com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseries -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.tracking.NoOpInteractionPredicate import com.datadog.android.rum.internal.tracking.NoOpUserActionTrackingStrategy import com.datadog.android.rum.internal.tracking.UserActionTrackingStrategy @@ -869,7 +869,7 @@ internal class RumFeatureTest { var writerAtFlushTime: DataWriter? = null doAnswer { writerAtFlushTime = testedFeature.dataWriter - }.whenever(mockDatadogMonitor).stopActiveTimeseries() + }.whenever(mockDatadogMonitor).stopTimeseries() // When testedFeature.onStop() @@ -904,7 +904,7 @@ internal class RumFeatureTest { val timeseries = createTimeseries(totalRamBytes = 0L, sessionId = fakeSessionId) // Then: only the CPU pipeline is created; the memory pipeline is skipped. - check(timeseries is RumSessionScopeTimeseries) + check(timeseries is DefaultTimeseriesCollector) assertThat(timeseries.pipelines).hasSize(1) } @@ -917,7 +917,7 @@ internal class RumFeatureTest { val timeseries = createTimeseries(totalRamBytes = fakeTotalRamBytes, sessionId = fakeSessionId) // Then: both the CPU and memory pipelines are created. - check(timeseries is RumSessionScopeTimeseries) + check(timeseries is DefaultTimeseriesCollector) assertThat(timeseries.pipelines).hasSize(2) } @@ -1918,7 +1918,7 @@ internal class RumFeatureTest { // Builds a timeseries collector for the given total device RAM (in bytes), bypassing the // ActivityManager read so the skip/collect/log behavior can be exercised deterministically. @OptIn(ExperimentalRumApi::class) - private fun createTimeseries(totalRamBytes: Long, sessionId: String): Timeseries = + private fun createTimeseries(totalRamBytes: Long, sessionId: String): TimeseriesCollector = testedFeature .createTimeseriesCollectingFactory( TimeseriesConfiguration.Builder().build(), diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt index f2e1e67b81..8a399a9d61 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt @@ -27,7 +27,7 @@ import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollect import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.startup.RumAppStartupTelemetryReporter -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -137,10 +137,10 @@ internal class RumApplicationScopeAttributePropagationTest { lateinit var mockSessionSampler: Sampler @Mock - lateinit var mockTimeseriesFactory: Timeseries.Factory + lateinit var mockCollectorFactory: TimeseriesCollector.Factory @Mock - lateinit var mockTimeseries: Timeseries + lateinit var mockCollector: TimeseriesCollector @Forgery lateinit var fakeEventTime: Time @@ -201,7 +201,7 @@ internal class RumApplicationScopeAttributePropagationTest { fakeRumSessionType = forge.aNullable { aValueFrom(RumSessionType::class.java) } whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn mockTimeseries + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector testedScope = RumApplicationScope( applicationId = fakeApplicationId, sdkCore = rumMonitor.mockSdkCore, @@ -224,7 +224,7 @@ internal class RumApplicationScopeAttributePropagationTest { rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesFactory = mockTimeseriesFactory + timeseriesCollectorFactory = mockCollectorFactory ) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt index 4547c169ce..7c41810eb5 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt @@ -30,7 +30,7 @@ import com.datadog.android.rum.internal.domain.state.ViewUIPerformanceReport import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -139,10 +139,10 @@ internal class RumApplicationScopeTest { lateinit var mockSessionSampler: Sampler @Mock - lateinit var mockTimeseriesFactory: Timeseries.Factory + lateinit var mockCollectorFactory: TimeseriesCollector.Factory @Mock - lateinit var mockTimeseries: Timeseries + lateinit var mockCollector: TimeseriesCollector @StringForgery(regex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}") lateinit var fakeApplicationId: String @@ -185,7 +185,7 @@ internal class RumApplicationScopeTest { whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn mockTimeseries + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector testedScope = RumApplicationScope( applicationId = fakeApplicationId, @@ -209,7 +209,7 @@ internal class RumApplicationScopeTest { rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesFactory = mockTimeseriesFactory + timeseriesCollectorFactory = mockCollectorFactory ) } @@ -243,7 +243,7 @@ internal class RumApplicationScopeTest { ) // Then - the child session uses the same factory we gave to the application scope - verify(mockTimeseriesFactory).create(eq(fakeApplicationId), any(), any()) + verify(mockCollectorFactory).create(eq(fakeApplicationId), any(), any()) } @Test @@ -282,7 +282,7 @@ internal class RumApplicationScopeTest { ) // Then - factory.create is invoked once per tracked session (initial + new) - verify(mockTimeseriesFactory, times(2)).create(eq(fakeApplicationId), any(), any()) + verify(mockCollectorFactory, times(2)).create(eq(fakeApplicationId), any(), any()) } @Test diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt index df8b816ce6..ccb7ca92d1 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt @@ -26,7 +26,7 @@ import com.datadog.android.rum.internal.domain.display.DisplayInfo import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -130,10 +130,10 @@ internal class RumSessionScopeAttributePropagationTest { lateinit var mockSessionSampler: Sampler @Mock - lateinit var mockTimeseriesFactory: Timeseries.Factory + lateinit var mockCollectorFactory: TimeseriesCollector.Factory @Mock - lateinit var mockTimeseries: Timeseries + lateinit var mockCollector: TimeseriesCollector lateinit var fakeParentAttributes: Map @@ -171,7 +171,7 @@ internal class RumSessionScopeAttributePropagationTest { fakeRumSessionType = forge.aNullable { aValueFrom(RumSessionType::class.java) } whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn mockTimeseries + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector testedScope = RumSessionScope( parentScope = mockParentScope, sdkCore = mockSdkCore, @@ -198,7 +198,7 @@ internal class RumSessionScopeAttributePropagationTest { rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesFactory = mockTimeseriesFactory + timeseriesCollectorFactory = mockCollectorFactory ) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt index 99bae97d64..8b0b4afb4e 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt @@ -37,8 +37,8 @@ import com.datadog.android.rum.internal.startup.RumSessionScopeStartupManager import com.datadog.android.rum.internal.startup.RumStartupScenario import com.datadog.android.rum.internal.startup.RumTTIDInfo import com.datadog.android.rum.internal.startup.testRumStartupScenarios -import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesFactory -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -197,10 +197,10 @@ internal class RumSessionScopeTest { private lateinit var mockRumSessionScopeStartupManager: RumSessionScopeStartupManager @Mock - private lateinit var mockTimeseriesFactory: Timeseries.Factory + private lateinit var mockCollectorFactory: TimeseriesCollector.Factory @Mock - private lateinit var mockTimeseries: Timeseries + private lateinit var mockCollector: TimeseriesCollector private lateinit var stubTimeProvider: StubTimeProvider @@ -230,7 +230,7 @@ internal class RumSessionScopeTest { whenever(mockDisplayInfoProvider.getState()) doReturn fakeDisplayInfo whenever(mockSessionSampler.sample(any())).thenReturn(true) whenever(mockSessionSampler.getSampleRate()).thenReturn(100f) - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn mockTimeseries + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector fakeParentAttributes = forge.exhaustiveAttributes() whenever(mockParentScope.getCustomAttributes()) doReturn fakeParentAttributes @@ -1858,7 +1858,7 @@ internal class RumSessionScopeTest { fun `M start timeseries via factory W renewSession { keepSession = true }`(forge: Forge) { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = null) - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent( @@ -1869,12 +1869,12 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseriesFactory).create( + verify(mockCollectorFactory).create( fakeParentContext.applicationId, testedScope.sessionId, fakeRumSessionType ?: RumSessionType.USER ) - verify(mockTimeseries).onSessionStart() + verify(mockCollector).onSessionStart() } @Test @@ -1882,13 +1882,13 @@ internal class RumSessionScopeTest { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = null) fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create( + verify(mockCollectorFactory).create( fakeParentContext.applicationId, testedScope.sessionId, RumSessionType.USER @@ -1904,13 +1904,13 @@ internal class RumSessionScopeTest { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = fakeResultId) fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create( + verify(mockCollectorFactory).create( fakeParentContext.applicationId, testedScope.sessionId, RumSessionType.SYNTHETICS @@ -1927,13 +1927,13 @@ internal class RumSessionScopeTest { fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = fakeResultId) val expectedSessionType = forge.aValueFrom(RumSessionType::class.java) fakeRumSessionType = expectedSessionType - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create( + verify(mockCollectorFactory).create( fakeParentContext.applicationId, testedScope.sessionId, expectedSessionType @@ -1948,13 +1948,13 @@ internal class RumSessionScopeTest { fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = null) val expectedSessionType = forge.aValueFrom(RumSessionType::class.java) fakeRumSessionType = expectedSessionType - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(expectedSessionType)) + verify(mockCollectorFactory).create(any(), any(), eq(expectedSessionType)) } @Test @@ -1965,13 +1965,13 @@ internal class RumSessionScopeTest { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = fakeResultId) fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) } @Test @@ -1982,13 +1982,13 @@ internal class RumSessionScopeTest { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = null) fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) } @Test @@ -1999,13 +1999,13 @@ internal class RumSessionScopeTest { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = " ", syntheticsResultId = fakeResultId) fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) } @Test @@ -2016,20 +2016,20 @@ internal class RumSessionScopeTest { // Given fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = " ") fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) } @Test fun `M not start timeseries W renewSession { keepSession = false }`(forge: Forge) { // Given whenever(mockSessionSampler.sample(any())).thenReturn(false) - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) // When testedScope.handleEvent( @@ -2040,14 +2040,14 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseriesFactory, never()).create(any(), any(), any()) - verify(mockTimeseries, never()).onSessionStart() + verify(mockCollectorFactory, never()).create(any(), any(), any()) + verify(mockCollector, never()).onSessionStart() } @Test fun `M stop previous timeseries W renewSession { another tracked session }`(forge: Forge) { // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2065,15 +2065,15 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseries).onSessionStop() - verify(mockTimeseriesFactory, times(2)).create(any(), any(), any()) - verify(mockTimeseries, times(2)).onSessionStart() + verify(mockCollector).onSessionStop() + verify(mockCollectorFactory, times(2)).create(any(), any(), any()) + verify(mockCollector, times(2)).onSessionStart() } @Test fun `M stop timeseries W handleEvent { session expires without renewal }`(forge: Forge) { // Given - initializeTestedScope(backgroundTrackingEnabled = false, timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(backgroundTrackingEnabled = false, timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2087,13 +2087,13 @@ internal class RumSessionScopeTest { // Then assertThat(testedScope.sessionState).isEqualTo(RumSessionScope.State.EXPIRED) - verify(mockTimeseries).onSessionStop() + verify(mockCollector).onSessionStop() } @Test fun `M stop timeseries W handleEvent { StopSession }`(forge: Forge) { // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2110,7 +2110,7 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseries).onSessionStop() + verify(mockCollector).onSessionStop() } @Test @@ -2125,13 +2125,13 @@ internal class RumSessionScopeTest { // Then assertThat(result).isSameAs(testedScope) - verifyNoInteractions(mockTimeseries, mockTimeseriesFactory) + verifyNoInteractions(mockCollector, mockCollectorFactory) } @Test fun `M notify timeseries of view type W handleEvent`(forge: Forge) { // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2148,7 +2148,7 @@ internal class RumSessionScopeTest { ) // Then — called once per handleEvent invocation - verify(mockTimeseries, times(2)).onViewTypeUpdate(any()) + verify(mockCollector, times(2)).onViewTypeUpdate(any()) } @Test @@ -2156,7 +2156,7 @@ internal class RumSessionScopeTest { // Given initializeTestedScope( withMockChildScope = false, - timeseriesFactory = mockTimeseriesFactory + timeseriesCollectorFactory = mockCollectorFactory ) // When @@ -2168,21 +2168,21 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseries).onViewTypeUpdate(RumViewType.FOREGROUND) - verify(mockTimeseries, never()).onViewTypeUpdate(RumViewType.NONE) + verify(mockCollector).onViewTypeUpdate(RumViewType.FOREGROUND) + verify(mockCollector, never()).onViewTypeUpdate(RumViewType.NONE) } @Test fun `M pass NONE W onViewTypeUpdate { no active view }`(forge: Forge) { // Given — activeView is null by default (mockChildScope.activeView not stubbed) - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // When testedScope.handleEvent(forge.addErrorEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseries, times(2)).onViewTypeUpdate(RumViewType.NONE) + verify(mockCollector, times(2)).onViewTypeUpdate(RumViewType.NONE) } @Test @@ -2192,14 +2192,14 @@ internal class RumSessionScopeTest { val fakeRumContext = forge.getForgery().copy(viewType = RumViewType.FOREGROUND) whenever(mockChildScope.activeView) doReturn mockViewScope whenever(mockViewScope.getRumContext()) doReturn fakeRumContext - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // When testedScope.handleEvent(forge.addErrorEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then — at least the last call carries FOREGROUND - verify(mockTimeseries, atLeastOnce()).onViewTypeUpdate(RumViewType.FOREGROUND) + verify(mockCollector, atLeastOnce()).onViewTypeUpdate(RumViewType.FOREGROUND) } @Test @@ -2209,7 +2209,7 @@ internal class RumSessionScopeTest { val fakeRumContext = forge.getForgery().copy(viewType = RumViewType.FOREGROUND) whenever(mockChildScope.activeView) doReturn mockViewScope whenever(mockViewScope.getRumContext()) doReturn fakeRumContext - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // When — expire session and start a new one @@ -2217,19 +2217,19 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then — second timeseries (same factory mock) also receives FOREGROUND right after start() - val inOrder = inOrder(mockTimeseries) - inOrder.verify(mockTimeseries, times(2)).onSessionStart() - inOrder.verify(mockTimeseries).onViewTypeUpdate(RumViewType.FOREGROUND) + val inOrder = inOrder(mockCollector) + inOrder.verify(mockCollector, times(2)).onSessionStart() + inOrder.verify(mockCollector).onViewTypeUpdate(RumViewType.FOREGROUND) } @Test fun `M stop previous timeseries W renewSession { ResetSession renews tracked session }`(forge: Forge) { // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - val firstTimeseries = mockTimeseries - val secondTimeseries: Timeseries = mock() - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn secondTimeseries + val firstCollector = mockCollector + val secondCollector: TimeseriesCollector = mock() + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector // When testedScope.handleEvent( @@ -2240,19 +2240,19 @@ internal class RumSessionScopeTest { ) // Then - verify(firstTimeseries).onSessionStart() - verify(firstTimeseries).onSessionStop() - verify(secondTimeseries).onSessionStart() + verify(firstCollector).onSessionStart() + verify(firstCollector).onSessionStop() + verify(secondCollector).onSessionStart() } @Test fun `M stop previous timeseries W renewSession { expired session then new interaction }`(forge: Forge) { // Given - initializeTestedScope(backgroundTrackingEnabled = false, timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(backgroundTrackingEnabled = false, timeseriesCollectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - val firstTimeseries = mockTimeseries - val secondTimeseries: Timeseries = mock() - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn secondTimeseries + val firstCollector = mockCollector + val secondCollector: TimeseriesCollector = mock() + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector advanceTimeByMs(TEST_INACTIVITY_MS) testedScope.handleEvent(mock(), fakeDatadogContext, mockEventWriteScope, mockWriter) @@ -2260,9 +2260,9 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startActionEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(firstTimeseries).onSessionStart() - verify(firstTimeseries).onSessionStop() - verify(secondTimeseries).onSessionStart() + verify(firstCollector).onSessionStart() + verify(firstCollector).onSessionStop() + verify(secondCollector).onSessionStart() } @Test @@ -2276,7 +2276,7 @@ internal class RumSessionScopeTest { ) // Then - verifyNoInteractions(mockTimeseries) + verifyNoInteractions(mockCollector) } // endregion @@ -2298,7 +2298,7 @@ internal class RumSessionScopeTest { sessionSampler: Sampler = mockSessionSampler, withMockChildScope: Boolean = true, backgroundTrackingEnabled: Boolean? = null, - timeseriesFactory: Timeseries.Factory = NoOpTimeseriesFactory() + timeseriesCollectorFactory: TimeseriesCollector.Factory = NoOpTimeseriesCollectorFactory() ) { testedScope = RumSessionScope( parentScope = mockParentScope, @@ -2326,7 +2326,7 @@ internal class RumSessionScopeTest { rumSessionScopeStartupManagerFactory = { mockRumSessionScopeStartupManager }, insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesFactory = timeseriesFactory + timeseriesCollectorFactory = timeseriesCollectorFactory ) if (withMockChildScope) { diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt index 5d32fefa68..da90ee57b8 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt @@ -56,7 +56,7 @@ import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.monitor.DatadogRumMonitor.Companion.OPERATION_ERROR_INVALID_NAME import com.datadog.android.rum.internal.monitor.DatadogRumMonitor.Companion.OPERATION_ERROR_INVALID_NAME_CHARACTERS import com.datadog.android.rum.internal.monitor.DatadogRumMonitor.Companion.OPERATION_ERROR_INVALID_OPERATION_KEY -import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesFactory +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -307,7 +307,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) testedMonitor.rootScope = mockApplicationScope } @@ -342,7 +342,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) // When @@ -420,7 +420,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) testedMonitor.start() val mockCallback = mock<(String?) -> Unit>() @@ -466,7 +466,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) testedMonitor.start() val mockCallback = mock<(String?) -> Unit>() @@ -2228,7 +2228,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) // When @@ -2271,7 +2271,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) // When @@ -2315,7 +2315,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) whenever(mockExecutorService.isShutdown).thenReturn(true) @@ -2541,7 +2541,7 @@ internal class DatadogRumMonitorTest { insightsCollector = mockInsightsCollector, appPackageName = fakeApplicationPackageName, heatmapIdentifierRegistry = null, - timeseriesFactory = NoOpTimeseriesFactory() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) testedMonitor.startView(key, name, attributes) // When @@ -2971,6 +2971,23 @@ internal class DatadogRumMonitorTest { // endregion + // region timeseries + + @Test + fun `M stop the active session timeseries W stopTimeseries()`() { + // Given + val mockSessionScope = mock() + whenever(mockApplicationScope.activeSession) doReturn mockSessionScope + + // When + testedMonitor.stopTimeseries() + + // Then + verify(mockSessionScope).stopTimeseries() + } + + // endregion + @OptIn(ExperimentalRumApi::class) @Test fun `M produce StartOperation event W startOperation`( diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactoryTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt similarity index 93% rename from features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactoryTest.kt rename to features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt index 16c418b19a..8d7002c889 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactoryTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt @@ -36,7 +36,7 @@ import java.util.concurrent.ScheduledExecutorService ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class RumSessionScopeTimeseriesFactoryTest { +internal class DefaultTimeseriesCollectorFactoryTest { @Mock lateinit var mockSdkCore: FeatureSdkCore @@ -51,7 +51,7 @@ internal class RumSessionScopeTimeseriesFactoryTest { lateinit var mockExecutor: ScheduledExecutorService @Test - fun `M build RumSessionScopeTimeseries with provided pipelines W create()`( + fun `M build DefaultTimeseriesCollector with provided pipelines W create()`( @StringForgery fakeSessionId: String, @StringForgery fakeApplicationId: String ) { @@ -64,7 +64,7 @@ internal class RumSessionScopeTimeseriesFactoryTest { whenever(this(fakeSessionId, fakeApplicationId, fakeSessionType)) .thenReturn(listOf(pipelineA, pipelineB)) } - val testedFactory = RumSessionScopeTimeseriesFactory( + val testedFactory = DefaultTimeseriesCollectorFactory( internalLogger = mockInternalLogger, collectInBackground = false, scheduledExecutorService = mockExecutor, @@ -86,7 +86,7 @@ internal class RumSessionScopeTimeseriesFactoryTest { ) { // Given val emptyProvider: (String, String, RumSessionType) -> List> = { _, _, _ -> emptyList() } - val testedFactory = RumSessionScopeTimeseriesFactory( + val testedFactory = DefaultTimeseriesCollectorFactory( internalLogger = mockInternalLogger, collectInBackground = true, scheduledExecutorService = mockExecutor, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt similarity index 97% rename from features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesTest.kt rename to features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt index 4429538af9..cc582c91bf 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt @@ -55,9 +55,9 @@ import java.util.concurrent.TimeUnit ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class RumSessionScopeTimeseriesTest { +internal class DefaultTimeseriesCollectorTest { - private lateinit var testedTimeseries: RumSessionScopeTimeseries + private lateinit var testedTimeseries: DefaultTimeseriesCollector @Mock lateinit var mockDataWriter: DataWriter @@ -127,7 +127,7 @@ internal class RumSessionScopeTimeseriesTest { pipelineA = Pipeline(mockSdkCore, mockReaderA, bufferA, mockSerializerA, mockDataWriter, mockInternalLogger) pipelineB = Pipeline(mockSdkCore, mockReaderB, bufferB, mockSerializerB, mockDataWriter, mockInternalLogger) - testedTimeseries = RumSessionScopeTimeseries( + testedTimeseries = DefaultTimeseriesCollector( pipelines = listOf(pipelineA, pipelineB), internalLogger = mockInternalLogger, collectInBackground = false, @@ -379,7 +379,7 @@ internal class RumSessionScopeTimeseriesTest { mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - RumSessionScopeTimeseries.ERROR_SAMPLING_FAILED, + DefaultTimeseriesCollector.ERROR_SAMPLING_FAILED, fakeError ) } @@ -387,7 +387,7 @@ internal class RumSessionScopeTimeseriesTest { @Test fun `M log error and reschedule W sample tick { buffer drain throws }`(forge: Forge) { // Given — drain() throws outside Pipeline's own try/catch, so it must be - // caught by RumSessionScopeTimeseries' sampling try/catch instead. + // caught by DefaultTimeseriesCollector' sampling try/catch instead. val fakeError = RuntimeException("drain failure") val mockBuffer = mock>() whenever(mockBuffer.isFull()) doReturn true @@ -395,7 +395,7 @@ internal class RumSessionScopeTimeseriesTest { whenever(mockReaderA.read()) doReturn forge.getForgery>() val pipeline = Pipeline(mockSdkCore, mockReaderA, mockBuffer, mockSerializerA, mockDataWriter, mockInternalLogger) - val timeseries = RumSessionScopeTimeseries( + val timeseries = DefaultTimeseriesCollector( pipelines = listOf(pipeline), internalLogger = mockInternalLogger, collectInBackground = false, @@ -412,7 +412,7 @@ internal class RumSessionScopeTimeseriesTest { mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - RumSessionScopeTimeseries.ERROR_SAMPLING_FAILED, + DefaultTimeseriesCollector.ERROR_SAMPLING_FAILED, fakeError ) verify(mockExecutor, times(2)) @@ -434,7 +434,7 @@ internal class RumSessionScopeTimeseriesTest { // Then // times(1) default on verifyLog also confirms this is the only ERROR log with that - // throwable — i.e. RumSessionScopeTimeseries' own sampling catch never fired here. + // throwable — i.e. DefaultTimeseriesCollector' own sampling catch never fired here. mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), @@ -463,7 +463,7 @@ internal class RumSessionScopeTimeseriesTest { mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - RumSessionScopeTimeseries.ERROR_SAMPLING_FAILED, + DefaultTimeseriesCollector.ERROR_SAMPLING_FAILED, fakeError ) verify(mockExecutor, times(fakeBufferSize + 1)) @@ -512,7 +512,7 @@ internal class RumSessionScopeTimeseriesTest { fun `M sample W sample tick { background, collectInBackground = true }`(forge: Forge) { // Given whenever(mockReaderA.read()) doReturn forge.getForgery>() - val bgTimeseries = RumSessionScopeTimeseries( + val bgTimeseries = DefaultTimeseriesCollector( pipelines = listOf(pipelineA, pipelineB), internalLogger = mockInternalLogger, collectInBackground = true, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvTimeseries.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt similarity index 91% rename from features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvTimeseries.kt rename to features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt index 7444584bd0..d61f8175fb 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvTimeseries.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt @@ -11,21 +11,21 @@ import com.datadog.android.internal.time.TimeProvider import com.datadog.android.rum.RumSessionType import com.datadog.android.rum.internal.domain.scope.RumViewType import com.datadog.android.rum.internal.timeseries.Buffer -import com.datadog.android.rum.internal.timeseries.Timeseries +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.timeseries.serializer.CpuEventSerializer import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer import com.datadog.android.rum.internal.timeseries.serializer.MemoryEventSerializer import com.google.gson.JsonObject /** - * A test-only [Timeseries] that mirrors the wiring done by `RumSessionScopeTimeseriesFactory`, + * A test-only [Timeseries] that mirrors the wiring done by `DefaultTimeseriesCollectorFactory`, * but pulls samples from CSV-backed readers instead of `VitalReaderWrapper` and drives the * pipelines synchronously (no executor) so callers can assert on every emitted JSON. */ -internal class CsvTimeseries( +internal class CsvCollector( private val pipelines: List, JsonSerializer>>, private val datadogContext: DatadogContext -) : Timeseries { +) : TimeseriesCollector { private val emitted = mutableListOf() @@ -58,7 +58,7 @@ internal class CsvTimeseries( companion object { /** - * Builds a [CsvTimeseries] with the same shape as `RumSessionScopeTimeseriesFactory`: + * Builds a [CsvCollector] with the same shape as `DefaultTimeseriesCollectorFactory`: * a memory pipeline followed by a CPU pipeline, each backed by [CSVReader] and the * production [MemoryEventSerializer] / [CpuEventSerializer]. */ @@ -72,7 +72,7 @@ internal class CsvTimeseries( bufferSize: Int, timeProvider: TimeProvider, datadogContext: DatadogContext - ) = CsvTimeseries( + ) = CsvCollector( datadogContext = datadogContext, pipelines = listOf( Triple( diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesEndToEndTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt similarity index 99% rename from features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesEndToEndTest.kt rename to features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt index 444b41f7ca..a99daaf644 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesEndToEndTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt @@ -40,7 +40,7 @@ import java.util.UUID ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class TimeseriesEndToEndTest { +internal class TimeseriesCollectorEndToEndTest { @Mock lateinit var mockTimeProvider: TimeProvider @@ -56,7 +56,7 @@ internal class TimeseriesEndToEndTest { whenever(mockTimeProvider.getDeviceTimestampMillis()) doReturn FIXED_DATE_MS csvContent = loadResource("fixtures/timeseries/input_memory_cpu.csv") - val testedTimeseries = CsvTimeseries.create( + val testedTimeseries = CsvCollector.create( csvContent = csvContent, sessionId = SESSION_ID, applicationId = APPLICATION_ID, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/VitalReaderDataPointsReaderTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt similarity index 94% rename from features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/VitalReaderDataPointsReaderTest.kt rename to features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt index 3650eec407..61b45e83c3 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/VitalReaderDataPointsReaderTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt @@ -4,10 +4,9 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.rum.internal.timeseries +package com.datadog.android.rum.internal.timeseries.provider import com.datadog.android.internal.time.TimeProvider -import com.datadog.android.rum.internal.timeseries.provider.VitalReaderWrapper import com.datadog.android.rum.internal.vitals.VitalReader import com.datadog.android.rum.utils.forge.Configurator import fr.xgouchet.elmyr.annotation.DoubleForgery @@ -34,7 +33,7 @@ import java.util.concurrent.TimeUnit ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class VitalReaderDataPointsReaderTest { +internal class VitalReaderWrapperTest { @LongForgery(min = 1L) var fakeTimestamp: Long = 0L From 2833c0470838f22d67dd78e209cbeac7dc52a722 Mon Sep 17 00:00:00 2001 From: Timur Valeev Date: Fri, 14 Aug 2026 14:34:23 +0100 Subject: [PATCH 2/4] RUM-17613 Flush the pending timeseries batch on backgrounding Replace the collector's four-state enum with a generation-counted state and schedule a 200 ms deferred suspension when the app leaves the foreground, so the buffered batch is written instead of dropped. Sampling only runs on a foreground view, which makes the collectInBackground switch obsolete. Ref: RUM-17613 --- detekt_custom_safe_calls_third_party.yml | 3 - .../android/rum/internal/RumFeature.kt | 1 - .../internal/domain/scope/RumSessionScope.kt | 3 +- .../timeseries/DefaultTimeseriesCollector.kt | 207 ++++++++---- .../DefaultTimeseriesCollectorFactory.kt | 20 +- .../timeseries/TimeseriesCollector.kt | 7 +- .../rum/timeseries/TimeseriesConfiguration.kt | 15 +- .../android/rum/internal/RumFeatureTest.kt | 3 +- ...pplicationScopeAttributePropagationTest.kt | 2 +- .../domain/scope/RumApplicationScopeTest.kt | 6 +- ...RumSessionScopeAttributePropagationTest.kt | 2 +- .../domain/scope/RumSessionScopeTest.kt | 48 +-- .../DefaultTimeseriesCollectorFactoryTest.kt | 73 +++- .../DefaultTimeseriesCollectorTest.kt | 317 +++++++++++++----- .../timeseries/TimeseriesConfigurationTest.kt | 18 - 15 files changed, 490 insertions(+), 235 deletions(-) diff --git a/detekt_custom_safe_calls_third_party.yml b/detekt_custom_safe_calls_third_party.yml index 9f3686b425..b1603c68dc 100644 --- a/detekt_custom_safe_calls_third_party.yml +++ b/detekt_custom_safe_calls_third_party.yml @@ -259,7 +259,6 @@ datadog: - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.api.SdkCore?, com.datadog.android.api.SdkCore?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.flags.internal.repository.DefaultFlagsRepository.FlagsState?, com.datadog.android.flags.internal.repository.DefaultFlagsRepository.FlagsState?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.trace.bootstrap.instrumentation.api.AgentTracer.TracerAPI?, com.datadog.trace.bootstrap.instrumentation.api.AgentTracer.TracerAPI?)" - - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?, com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(com.datadog.android.trace.api.tracer.DatadogTracer?, com.datadog.android.trace.api.tracer.DatadogTracer?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(kotlin.String?, kotlin.String?)" - "java.util.concurrent.atomic.AtomicReference.compareAndSet(kotlin.collections.Set?, kotlin.collections.Set?)" @@ -272,14 +271,12 @@ datadog: - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.flags.model.FlagsClientState?)" - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.flags.model.ProviderContext?)" - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.rum.internal.domain.RumContext?)" - - "java.util.concurrent.atomic.AtomicReference.constructor(com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?)" - "java.util.concurrent.atomic.AtomicReference.constructor(kotlin.collections.Map?)" - "java.util.concurrent.atomic.AtomicReference.constructor(kotlin.String?)" - "java.util.concurrent.atomic.AtomicReference.constructor(kotlin.collections.Set?)" - "java.util.concurrent.atomic.AtomicReference.get()" - "java.util.concurrent.atomic.AtomicReference.getAndSet(kotlin.String?)" - "java.util.concurrent.atomic.AtomicReference.getAndSet(java.util.concurrent.Future?)" - - "java.util.concurrent.atomic.AtomicReference.getAndSet(com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector.State?)" - "java.util.concurrent.atomic.AtomicReference.set(android.app.Application.ActivityLifecycleCallbacks?)" - "java.util.concurrent.atomic.AtomicReference.set(com.datadog.android.api.FeatureEventReceiver?)" - "java.util.concurrent.atomic.AtomicReference.set(com.datadog.android.api.SdkCore?)" diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt index 89c48906c6..64e93cfd17 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt @@ -459,7 +459,6 @@ internal class RumFeature( insightsCollector: InsightsCollector ): TimeseriesCollector.Factory = DefaultTimeseriesCollectorFactory( internalLogger = sdkCore.internalLogger, - collectInBackground = configuration.collectInBackground, scheduledExecutorService = vitalExecutorService, pipelinesProvider = { applicationId, sessionId, sessionType -> listOfNotNull( diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt index 618f28c7db..0e799a5dc0 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt @@ -237,7 +237,8 @@ internal class RumSessionScope( timeseriesCollector = timeseriesCollectorFactory.create( sessionId = sessionId, applicationId = parentScope.getRumContext().applicationId, - sessionType = getRumContext().resolveSessionType(rumSessionTypeOverride) + sessionType = getRumContext().resolveSessionType(rumSessionTypeOverride), + viewType = getActiveRumContext().viewType ) timeseriesCollector.onSessionStart() } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt index 506506ac77..e50d088f44 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt @@ -11,102 +11,104 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.core.internal.utils.scheduleSafe import com.datadog.android.rum.internal.domain.scope.RumViewType import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger -import java.util.concurrent.atomic.AtomicReference /** * Per-session timeseries collector. * - * Lifecycle invariants (enforced by [onSessionStart]/[onSessionStop] idempotency): + * Lifecycle: * - Each instance is single-use: exactly one [onSessionStart] followed by exactly one [onSessionStop]. - * - Multiple [onSessionStart] / [onSessionStop] calls are safe — duplicate calls are no-ops. - * - After [onSessionStop], the instance must not be restarted; create a new instance. + * Duplicate calls are no-ops, and `RumSessionScope` builds a fresh instance per session. + * - [onViewTypeUpdate] is only meaningful between those two calls. * - * Background sampling: - * - When [collectInBackground] is `false`, [onViewTypeUpdate] pauses sampling on leaving foreground - * and resumes it on returning to foreground. + * Foreground gating: + * - Sampling only runs while the app is in the foreground, so [onSessionStart] starts a sampling + * chain only when the session begins on a foreground view. + * - Leaving the foreground schedules a deferred suspension which flushes whatever is buffered, so + * the pending batch reaches the writer instead of being dropped when the app is backgrounded. + * - Returning to the foreground cancels a suspension that has not fired yet, or starts a fresh + * sampling generation if it already did. * * Threading: * - [onSessionStart] / [onSessionStop] / [onViewTypeUpdate] are called from the RUM event-handler thread. - * - Sampling tasks run on a [scheduledExecutorService] shared with other RUM components - * (owned by the SDK core); the instance neither owns nor shuts it down. - * - [Pipeline] is responsible for its own thread safety via internal synchronization. - * - Duplicate-chain prevention: each sampling chain carries a generation number. - * When [startSampling] starts a new generation, any in-flight or queued ticks from the - * previous generation self-terminate on their first check. + * - Sampling and suspension tasks run on a [scheduledExecutorService] shared with other RUM + * components (owned by the SDK core); the instance neither owns nor shuts it down. + * - Access to a [Pipeline] is serialized on the pipeline instance, so a flush from the suspension + * task cannot interleave with a sampling tick. + * - Duplicate-chain prevention: each sampling chain carries a generation number. When a new + * generation starts, in-flight or queued ticks from the previous one self-terminate on their + * first check. */ internal class DefaultTimeseriesCollector( private val internalLogger: InternalLogger, internal val pipelines: List>, - private val collectInBackground: Boolean, - internal val scheduledExecutorService: ScheduledExecutorService + internal val scheduledExecutorService: ScheduledExecutorService, + @Volatile private var currentViewType: RumViewType? ) : TimeseriesCollector { - private enum class State { IDLE, RUNNING, SUSPENDED, STOPPED } - private val state = AtomicReference(State.IDLE) - - // Incremented on every start/resume. Ticks carrying a stale generation self-terminate. - private val currentGeneration = AtomicInteger(0) + private val state = State() @Volatile - private var currentViewType: RumViewType? = null + private var recentSuspension: ScheduledFuture<*>? = null + + // region PUBLIC API @WorkerThread override fun onSessionStart() { - if (state.compareAndSet(State.IDLE, State.RUNNING)) { - startSampling() - } + state.set(isActive = currentViewType.isForeground)?.let { generation -> scheduleSampling(generation) } } @WorkerThread override fun onSessionStop() { - if (state.getAndSet(State.STOPPED) != State.STOPPED) { - pipelines.forEach { pipeline -> - try { - synchronized(pipeline, pipeline::flush) - } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { - internalLogger.log( - level = InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - messageBuilder = { ERROR_FLUSH_FAILED }, - throwable = t - ) - } - } + cancelSuspension() + if (state.set(false) != null) { + flushPipelines() } } @WorkerThread override fun onViewTypeUpdate(newViewType: RumViewType) { - if (newViewType == currentViewType) return - val isEnterForeground = !currentViewType.isForeground && newViewType.isForeground + val oldViewType = currentViewType + if (newViewType == oldViewType) return + + val isEnterForeground = !oldViewType.isForeground && newViewType.isForeground + val isLeaveForeground = oldViewType.isForeground && !newViewType.isForeground + currentViewType = newViewType - if (!collectInBackground) { - if (isEnterForeground && state.compareAndSet(State.SUSPENDED, State.RUNNING)) { - startSampling() - } else if (!newViewType.isForeground) { - state.compareAndSet(State.RUNNING, State.SUSPENDED) - } + + if (isLeaveForeground) { + scheduleStop(state.currentGeneration) + } else if (isEnterForeground) { + scheduleSampling(generation = state.startGeneration()) } } - private fun startSampling() { - val generation = currentGeneration.incrementAndGet() - pipelines.forEach { schedulePipeline(it, generation) } + // endregion + + // region SAMPLING + + private fun scheduleSampling(generation: Int) { + cancelSuspension() + pipelines.forEach { pipeline -> scheduledExecutorService.schedulePipeline(pipeline, generation) } } - private fun schedulePipeline(pipeline: Pipeline<*>, generation: Int) { - scheduledExecutorService.scheduleSafe( - OPERATION_NAME, + private fun ScheduledExecutorService.schedulePipeline( + pipeline: Pipeline<*>, + generation: Int + ) { + scheduleSafe( + TIMESERIES_OPERATION_NAME, pipeline.intervalMs, TimeUnit.MILLISECONDS, internalLogger ) { - if (!isActive(generation)) return@scheduleSafe + if (!state.isGenerationActive(generation)) return@scheduleSafe try { - synchronized(pipeline) { - if (isActive(generation)) pipeline.execute() + // The chain stays alive during the suspension delay, so a tick landing while the + // app is already out of the foreground must skip the sample but keep the chain. + if (currentViewType.isForeground) { + synchronized(pipeline) { pipeline.execute() } } } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { internalLogger.log( @@ -116,18 +118,62 @@ internal class DefaultTimeseriesCollector( throwable = t ) } finally { - if (isActive(generation)) schedulePipeline(pipeline, generation) + if (state.isGenerationActive(generation)) schedulePipeline(pipeline, generation) + } + } + } + + @WorkerThread + private fun flushPipelines() { + pipelines.forEach { pipeline -> + try { + synchronized(pipeline, pipeline::flush) + } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { + internalLogger.log( + level = InternalLogger.Level.ERROR, + targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), + messageBuilder = { ERROR_FLUSH_FAILED }, + throwable = t + ) + } + } + } + + // endregion + + // region SUSPENSION + + private fun scheduleStop(stopRequestGeneration: Int) { + recentSuspension = scheduledExecutorService.scheduleSafe( + SUSPEND_OPERATION_NAME, + SUSPEND_DELAY_MS, + TimeUnit.MILLISECONDS, + internalLogger + ) { + if (!currentViewType.isForeground && state.stopGeneration(stopRequestGeneration)) { + flushPipelines() } } } - private fun isActive(generation: Int): Boolean = - state.get() == State.RUNNING && currentGeneration.get() == generation + private fun cancelSuspension() { + recentSuspension?.cancel(false) + recentSuspension = null + } + + // endregion internal companion object { - const val OPERATION_NAME = "Timeseries sampling" + const val TIMESERIES_OPERATION_NAME = "Timeseries sampling" + const val SUSPEND_OPERATION_NAME = "Timeseries suspend" const val ERROR_SAMPLING_FAILED = "Timeseries sampling iteration failed; rescheduling next sample." - const val ERROR_FLUSH_FAILED = "Timeseries flush on session stop failed." + const val ERROR_FLUSH_FAILED = "Timeseries flush failed." + + // Matches ActivityViewTrackingStrategy.STOP_VIEW_DELAY_MS, which guards the same race: + // an Activity-to-Activity transition leaves no active view for a moment when the tracking + // strategy stops the view on pause rather than on stop. + const val SUSPEND_DELAY_MS = 200L + val RumViewType?.isForeground: Boolean get() = when (this) { RumViewType.FOREGROUND, RumViewType.APPLICATION_LAUNCH -> true @@ -135,5 +181,46 @@ internal class DefaultTimeseriesCollector( RumViewType.NONE -> false null -> false } + + private class State { + // Written under the monitor only, but read outside of it, hence @Volatile: a stale + // generation would make the guards below reject a live sampling chain or flush. + @Volatile + var currentGeneration: Int = 0 + private set + + private var active: Boolean = false + + fun isGenerationActive(generation: Int): Boolean = synchronized(this) { + currentGeneration == generation && active + } + + /** + * Always starts a fresh generation, so that a suspension pending on the previous one + * can no longer stop the sampling chain. Returns the new generation. + */ + fun startGeneration(): Int = synchronized(this) { + active = true + ++currentGeneration + } + + /** + * Deactivates [generation] if it is still the current one. + * Returns true when this call is the one that deactivated it. + */ + fun stopGeneration(generation: Int): Boolean = synchronized(this) { + currentGeneration == generation && set(false) != null + } + + /** Returns the new generation if this call changed the state, null otherwise. */ + fun set(isActive: Boolean): Int? = synchronized(this) { + if (isActive == active) { + null + } else { + active = isActive + ++currentGeneration + } + } + } } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt index bec629e64e..218a681151 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt @@ -8,11 +8,11 @@ package com.datadog.android.rum.internal.timeseries import com.datadog.android.api.InternalLogger import com.datadog.android.rum.RumSessionType +import com.datadog.android.rum.internal.domain.scope.RumViewType import java.util.concurrent.ScheduledExecutorService internal class DefaultTimeseriesCollectorFactory( private val internalLogger: InternalLogger, - private val collectInBackground: Boolean, private val scheduledExecutorService: ScheduledExecutorService, private val pipelinesProvider: ( applicationId: String, @@ -21,11 +21,15 @@ internal class DefaultTimeseriesCollectorFactory( ) -> List> ) : TimeseriesCollector.Factory { - override fun create(applicationId: String, sessionId: String, sessionType: RumSessionType) = - DefaultTimeseriesCollector( - internalLogger = internalLogger, - collectInBackground = collectInBackground, - scheduledExecutorService = scheduledExecutorService, - pipelines = pipelinesProvider(applicationId, sessionId, sessionType) - ) + override fun create( + applicationId: String, + sessionId: String, + sessionType: RumSessionType, + viewType: RumViewType? + ) = DefaultTimeseriesCollector( + internalLogger = internalLogger, + scheduledExecutorService = scheduledExecutorService, + currentViewType = viewType, + pipelines = pipelinesProvider(applicationId, sessionId, sessionType) + ) } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt index 93fc71ec3f..2fd568dc57 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt @@ -18,6 +18,11 @@ internal interface TimeseriesCollector { @NoOpImplementation interface Factory { - fun create(applicationId: String, sessionId: String, sessionType: RumSessionType): TimeseriesCollector + fun create( + applicationId: String, + sessionId: String, + sessionType: RumSessionType, + viewType: RumViewType? + ): TimeseriesCollector } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt index 2b9e762483..d60314638a 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt @@ -18,8 +18,7 @@ import com.datadog.android.rum.timeseries.TimeseriesConfiguration.Companion.MIN_ */ class TimeseriesConfiguration internal constructor( internal val bufferSize: Int, - internal val intervalMs: Long, - internal val collectInBackground: Boolean + internal val intervalMs: Long ) { /** @@ -30,7 +29,6 @@ class TimeseriesConfiguration internal constructor( private var bufferSize: Int = DEFAULT_BUFFER_SIZE private var intervalMs: Long = DEFAULT_INTERVAL_MS - private var collectInBackground: Boolean = false /** * Sets the number of samples accumulated per pipeline before sending a batch event. @@ -54,19 +52,10 @@ class TimeseriesConfiguration internal constructor( this.intervalMs = if (intervalMs >= MIN_INTERVAL_MS) intervalMs else DEFAULT_INTERVAL_MS } - /** - * Sets whether to keep sampling timeseries when the app is in background. - * Defaults to `false`. - */ - internal fun collectInBackground(collectInBackground: Boolean): Builder = apply { - this.collectInBackground = collectInBackground - } - /** Builds a [TimeseriesConfiguration] from the current builder state. */ fun build(): TimeseriesConfiguration = TimeseriesConfiguration( bufferSize = bufferSize, - intervalMs = intervalMs, - collectInBackground = collectInBackground + intervalMs = intervalMs ) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt index bb3139225d..911a74b94e 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt @@ -50,6 +50,7 @@ import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilitySn import com.datadog.android.rum.internal.domain.battery.DefaultBatteryInfoProvider import com.datadog.android.rum.internal.domain.display.DefaultDisplayInfoProvider import com.datadog.android.rum.internal.domain.event.RumEventMapper +import com.datadog.android.rum.internal.domain.scope.RumViewType import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.monitor.AdvancedRumMonitor import com.datadog.android.rum.internal.monitor.DatadogRumMonitor @@ -1925,7 +1926,7 @@ internal class RumFeatureTest { totalRamBytes, testedFeature.configuration.insightsCollector ) - .create(fakeApplicationId.toString(), sessionId, RumSessionType.USER) + .create(fakeApplicationId.toString(), sessionId, RumSessionType.USER, RumViewType.FOREGROUND) private fun Forge.anApplicationExitInfoList( mustInclude: Int? = null diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt index 8a399a9d61..71f32ae9a1 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt @@ -201,7 +201,7 @@ internal class RumApplicationScopeAttributePropagationTest { fakeRumSessionType = forge.aNullable { aValueFrom(RumSessionType::class.java) } whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector + whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector testedScope = RumApplicationScope( applicationId = fakeApplicationId, sdkCore = rumMonitor.mockSdkCore, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt index 7c41810eb5..8c48a62525 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt @@ -185,7 +185,7 @@ internal class RumApplicationScopeTest { whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector + whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector testedScope = RumApplicationScope( applicationId = fakeApplicationId, @@ -243,7 +243,7 @@ internal class RumApplicationScopeTest { ) // Then - the child session uses the same factory we gave to the application scope - verify(mockCollectorFactory).create(eq(fakeApplicationId), any(), any()) + verify(mockCollectorFactory).create(eq(fakeApplicationId), any(), any(), any()) } @Test @@ -282,7 +282,7 @@ internal class RumApplicationScopeTest { ) // Then - factory.create is invoked once per tracked session (initial + new) - verify(mockCollectorFactory, times(2)).create(eq(fakeApplicationId), any(), any()) + verify(mockCollectorFactory, times(2)).create(eq(fakeApplicationId), any(), any(), any()) } @Test diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt index ccb7ca92d1..6c5eea380e 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt @@ -171,7 +171,7 @@ internal class RumSessionScopeAttributePropagationTest { fakeRumSessionType = forge.aNullable { aValueFrom(RumSessionType::class.java) } whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector + whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector testedScope = RumSessionScope( parentScope = mockParentScope, sdkCore = mockSdkCore, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt index 8b0b4afb4e..d167924e1a 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt @@ -230,7 +230,7 @@ internal class RumSessionScopeTest { whenever(mockDisplayInfoProvider.getState()) doReturn fakeDisplayInfo whenever(mockSessionSampler.sample(any())).thenReturn(true) whenever(mockSessionSampler.getSampleRate()).thenReturn(100f) - whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector + whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector fakeParentAttributes = forge.exhaustiveAttributes() whenever(mockParentScope.getCustomAttributes()) doReturn fakeParentAttributes @@ -1870,9 +1870,10 @@ internal class RumSessionScopeTest { // Then verify(mockCollectorFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - fakeRumSessionType ?: RumSessionType.USER + eq(fakeParentContext.applicationId), + eq(testedScope.sessionId), + eq(fakeRumSessionType ?: RumSessionType.USER), + any() ) verify(mockCollector).onSessionStart() } @@ -1889,9 +1890,10 @@ internal class RumSessionScopeTest { // Then verify(mockCollectorFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - RumSessionType.USER + eq(fakeParentContext.applicationId), + eq(testedScope.sessionId), + eq(RumSessionType.USER), + any() ) } @@ -1911,9 +1913,10 @@ internal class RumSessionScopeTest { // Then verify(mockCollectorFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - RumSessionType.SYNTHETICS + eq(fakeParentContext.applicationId), + eq(testedScope.sessionId), + eq(RumSessionType.SYNTHETICS), + any() ) } @@ -1934,9 +1937,10 @@ internal class RumSessionScopeTest { // Then verify(mockCollectorFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - expectedSessionType + eq(fakeParentContext.applicationId), + eq(testedScope.sessionId), + eq(expectedSessionType), + any() ) } @@ -1954,7 +1958,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockCollectorFactory).create(any(), any(), eq(expectedSessionType)) + verify(mockCollectorFactory).create(any(), any(), eq(expectedSessionType), any()) } @Test @@ -1971,7 +1975,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) } @Test @@ -1988,7 +1992,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) } @Test @@ -2005,7 +2009,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) } @Test @@ -2022,7 +2026,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER)) + verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) } @Test @@ -2040,7 +2044,7 @@ internal class RumSessionScopeTest { ) // Then - verify(mockCollectorFactory, never()).create(any(), any(), any()) + verify(mockCollectorFactory, never()).create(any(), any(), any(), any()) verify(mockCollector, never()).onSessionStart() } @@ -2066,7 +2070,7 @@ internal class RumSessionScopeTest { // Then verify(mockCollector).onSessionStop() - verify(mockCollectorFactory, times(2)).create(any(), any(), any()) + verify(mockCollectorFactory, times(2)).create(any(), any(), any(), any()) verify(mockCollector, times(2)).onSessionStart() } @@ -2229,7 +2233,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) val firstCollector = mockCollector val secondCollector: TimeseriesCollector = mock() - whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector + whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn secondCollector // When testedScope.handleEvent( @@ -2252,7 +2256,7 @@ internal class RumSessionScopeTest { testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) val firstCollector = mockCollector val secondCollector: TimeseriesCollector = mock() - whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector + whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn secondCollector advanceTimeByMs(TEST_INACTIVITY_MS) testedScope.handleEvent(mock(), fakeDatadogContext, mockEventWriteScope, mockWriter) diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt index 8d7002c889..208c84b1bd 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt @@ -10,6 +10,7 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter import com.datadog.android.rum.RumSessionType +import com.datadog.android.rum.internal.domain.scope.RumViewType import com.datadog.android.rum.internal.timeseries.provider.DataPointsReader import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer import com.datadog.android.rum.utils.forge.Configurator @@ -18,17 +19,23 @@ import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow 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.EnumSource 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.doReturn +import org.mockito.kotlin.eq 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 import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.TimeUnit @Extensions( ExtendWith(MockitoExtension::class), @@ -66,42 +73,80 @@ internal class DefaultTimeseriesCollectorFactoryTest { } val testedFactory = DefaultTimeseriesCollectorFactory( internalLogger = mockInternalLogger, - collectInBackground = false, scheduledExecutorService = mockExecutor, pipelinesProvider = provider ) // When - val timeseries = testedFactory.create(fakeSessionId, fakeApplicationId, fakeSessionType) + val timeseries = testedFactory.create( + fakeSessionId, + fakeApplicationId, + fakeSessionType, + RumViewType.FOREGROUND + ) // Then verify(provider).invoke(fakeSessionId, fakeApplicationId, fakeSessionType) assertThat(timeseries.scheduledExecutorService).isSameAs(mockExecutor) + assertThat(timeseries.pipelines).containsExactly(pipelineA, pipelineB) } - @Test - fun `M propagate collectInBackground flag W create()`( + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["FOREGROUND", "APPLICATION_LAUNCH"]) + fun `M seed collector with provided view type W create() { foreground view }`( + fakeViewType: RumViewType, + @StringForgery fakeSessionId: String, + @StringForgery fakeApplicationId: String + ) { + // Given + val timeseries = createCollectorSeededWith(fakeViewType, fakeSessionId, fakeApplicationId) + + // When + timeseries.onSessionStart() + + // Then — the seeded view type is a foreground one, so sampling starts right away + verify(mockExecutor).schedule(any(), eq(FAKE_INTERVAL_MS), eq(TimeUnit.MILLISECONDS)) + } + + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) + fun `M seed collector with provided view type W create() { non-foreground view }`( + fakeViewType: RumViewType, @StringForgery fakeSessionId: String, @StringForgery fakeApplicationId: String ) { // Given - val emptyProvider: (String, String, RumSessionType) -> List> = { _, _, _ -> emptyList() } + val timeseries = createCollectorSeededWith(fakeViewType, fakeSessionId, fakeApplicationId) + + // When + timeseries.onSessionStart() + + // Then — a session starting outside the foreground must not schedule any sampling + verify(mockExecutor, never()).schedule(any(), any(), any()) + } + + private fun createCollectorSeededWith( + viewType: RumViewType, + sessionId: String, + applicationId: String + ): TimeseriesCollector { val testedFactory = DefaultTimeseriesCollectorFactory( internalLogger = mockInternalLogger, - collectInBackground = true, scheduledExecutorService = mockExecutor, - pipelinesProvider = emptyProvider + pipelinesProvider = { _, _, _ -> listOf(mockPipeline()) } ) - - // When / Then - assertDoesNotThrow { - testedFactory.create(fakeSessionId, fakeApplicationId, RumSessionType.USER) - } + return testedFactory.create(sessionId, applicationId, RumSessionType.USER, viewType) } private fun mockPipeline(): Pipeline<*> { - val reader = mock>() + val reader = mock> { + on { intervalMs } doReturn FAKE_INTERVAL_MS + } val serializer = mock>() return Pipeline(mockSdkCore, reader, Buffer(1), serializer, mockWriter, mockInternalLogger) } + + private companion object { + const val FAKE_INTERVAL_MS = 1_000L + } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt index cc582c91bf..bf39ce791b 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt @@ -30,11 +30,14 @@ 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.EnumSource 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.argumentCaptor +import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.doThrow @@ -43,6 +46,7 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.times import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.mockito.quality.Strictness import java.util.concurrent.ScheduledExecutorService @@ -80,6 +84,9 @@ internal class DefaultTimeseriesCollectorTest { @Mock lateinit var mockExecutor: ScheduledExecutorService + @Mock + lateinit var mockScheduledFuture: ScheduledFuture<*> + @Mock lateinit var mockReaderA: DataPointsReader @@ -98,7 +105,7 @@ internal class DefaultTimeseriesCollectorTest { private lateinit var pipelineA: Pipeline private lateinit var pipelineB: Pipeline - @LongForgery(min = 1L, max = 60_000L) + @LongForgery(min = 1_000L, max = 60_000L) var fakeIntervalAMs: Long = 0L @LongForgery(min = 60_001L, max = 120_000L) @@ -111,7 +118,7 @@ internal class DefaultTimeseriesCollectorTest { fun `set up`() { whenever(mockReaderA.intervalMs) doReturn fakeIntervalAMs whenever(mockReaderB.intervalMs) doReturn fakeIntervalBMs - whenever(mockExecutor.schedule(any(), any(), any())) doReturn mock>() + whenever(mockExecutor.schedule(any(), any(), any())) doReturn mockScheduledFuture whenever(mockSdkCore.internalLogger) doReturn mockInternalLogger whenever(mockSdkCore.getFeature(Feature.RUM_FEATURE_NAME)) doReturn mockRumFeatureScope whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { inv -> @@ -127,14 +134,7 @@ internal class DefaultTimeseriesCollectorTest { pipelineA = Pipeline(mockSdkCore, mockReaderA, bufferA, mockSerializerA, mockDataWriter, mockInternalLogger) pipelineB = Pipeline(mockSdkCore, mockReaderB, bufferB, mockSerializerB, mockDataWriter, mockInternalLogger) - testedTimeseries = DefaultTimeseriesCollector( - pipelines = listOf(pipelineA, pipelineB), - internalLogger = mockInternalLogger, - collectInBackground = false, - scheduledExecutorService = mockExecutor - ) - // Seed FOREGROUND so sampling tests don't suspend on first tick - testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) + testedTimeseries = createCollector(RumViewType.FOREGROUND) } @Test @@ -322,28 +322,6 @@ internal class DefaultTimeseriesCollectorTest { testedTimeseries.onSessionStop() } - @Test - fun `M not start after stop W onSessionStart() { called after onSessionStop() }`() { - // Given - testedTimeseries.onSessionStart() - testedTimeseries.onSessionStop() - - // When - testedTimeseries.onSessionStart() - - // Then — no additional schedules beyond the original start - verify(mockExecutor).schedule( - any(), - eq(fakeIntervalAMs), - eq(TimeUnit.MILLISECONDS) - ) - verify(mockExecutor).schedule( - any(), - eq(fakeIntervalBMs), - eq(TimeUnit.MILLISECONDS) - ) - } - @Test fun `M continue scheduling W sample tick { reader throws }`() { // Given @@ -395,13 +373,7 @@ internal class DefaultTimeseriesCollectorTest { whenever(mockReaderA.read()) doReturn forge.getForgery>() val pipeline = Pipeline(mockSdkCore, mockReaderA, mockBuffer, mockSerializerA, mockDataWriter, mockInternalLogger) - val timeseries = DefaultTimeseriesCollector( - pipelines = listOf(pipeline), - internalLogger = mockInternalLogger, - collectInBackground = false, - scheduledExecutorService = mockExecutor - ) - timeseries.onViewTypeUpdate(RumViewType.FOREGROUND) + val timeseries = createCollector(RumViewType.FOREGROUND, listOf(pipeline)) timeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) @@ -488,12 +460,149 @@ internal class DefaultTimeseriesCollectorTest { ) } + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) + fun `M not schedule W onSessionStart() { initial view is not foreground }`( + initialViewType: RumViewType + ) { + // Given + val timeseries = createCollector(initialViewType) + + // When + timeseries.onSessionStart() + + // Then + verify(mockExecutor, never()).schedule(any(), any(), any()) + } + + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["FOREGROUND", "APPLICATION_LAUNCH"]) + fun `M neither flush nor schedule suspend W onViewTypeUpdate() { stays foreground }`( + nextViewType: RumViewType, + forge: Forge + ) { + // Given + whenever(mockReaderA.read()) doReturn forge.getForgery>() + testedTimeseries.onSessionStart() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A + + // When + testedTimeseries.onViewTypeUpdate(nextViewType) + + // Then — no suspend is even scheduled, so nothing can flush later either + verify(mockExecutor, never()) + .schedule(any(), eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), eq(TimeUnit.MILLISECONDS)) + verifyNoInteractions(mockSerializerA) + verifyNoInteractions(mockDataWriter) + } + + @Test + fun `M not flush W onViewTypeUpdate() { suspend not fired yet }`(forge: Forge) { + // Given + whenever(mockReaderA.read()) doReturn forge.getForgery>() + testedTimeseries.onSessionStart() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A + + // When — leaving the foreground only schedules the suspend, it does not flush inline + testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + + // Then + verify(mockExecutor) + .schedule(any(), eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), eq(TimeUnit.MILLISECONDS)) + verifyNoInteractions(mockSerializerA) + verifyNoInteractions(mockDataWriter) + } + + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) + fun `M flush partial buffer W pending suspend fires { left foreground }`( + nextViewType: RumViewType, + forge: Forge + ) { + // Given + val fakeSample = forge.getForgery>() + val fakeJson = JsonObject().apply { addProperty("fake-key", "fake-value") } + whenever(mockReaderA.read()) doReturn fakeSample + whenever(mockSerializerA.serialize(any(), eq(listOf(fakeSample)))) doReturn fakeJson + testedTimeseries.onSessionStart() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A + testedTimeseries.onViewTypeUpdate(nextViewType) + + // When + runScheduledSuspend() + + // Then — the batch buffered while in the foreground still reaches the writer + verify(mockSerializerA).serialize(any(), eq(listOf(fakeSample))) + verify(mockDataWriter).write(mockEventBatchWriter, fakeJson, EventType.DEFAULT) + // pipeline B never sampled, so its empty buffer must not produce an event + verify(mockSerializerB, never()).serialize(any(), any()) + } + + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) + fun `M flush W onSessionStop() { left foreground, suspend pending }`( + nextViewType: RumViewType, + forge: Forge + ) { + // Given + val fakeSample = forge.getForgery>() + whenever(mockReaderA.read()) doReturn fakeSample + whenever(mockSerializerA.serialize(any(), any())) doReturn JsonObject() + testedTimeseries.onSessionStart() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A + testedTimeseries.onViewTypeUpdate(nextViewType) + + // When — the session is stopped before the pending suspend had a chance to flush + testedTimeseries.onSessionStop() + + // Then + verify(mockSerializerA).serialize(any(), eq(listOf(fakeSample))) + } + @Test - fun `M suspend chain W sample tick { background, collectInBackground = false }`(forge: Forge) { + fun `M not flush twice W pending suspend fires { session already stopped }`() { + // Given + val mockBuffer = mock>() + val pipeline = + Pipeline(mockSdkCore, mockReaderA, mockBuffer, mockSerializerA, mockDataWriter, mockInternalLogger) + val timeseries = createCollector(RumViewType.FOREGROUND, listOf(pipeline)) + timeseries.onSessionStart() + timeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + timeseries.onSessionStop() // drains the buffer synchronously + + // When + runScheduledSuspend() + + // Then — the pending suspend targets a stale generation and must not drain again + verify(mockBuffer).drain() + } + + @ParameterizedTest + @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) + fun `M skip sample and reschedule W sample tick { foreground exit is pending }`( + nextViewType: RumViewType + ) { + // Given + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onViewTypeUpdate(nextViewType) + + // When — the suspend has not fired yet, so the chain is still alive + runnableA.run() + + // Then + verify(mockReaderA, never()).read() + verify(mockExecutor, times(2)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + } + + @Test + fun `M suspend chain W sample tick { suspend fired after background }`(forge: Forge) { // Given whenever(mockReaderA.read()) doReturn forge.getForgery>() testedTimeseries.onSessionStart() testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + runScheduledSuspend() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) // When @@ -509,94 +618,126 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M sample W sample tick { background, collectInBackground = true }`(forge: Forge) { + fun `M cancel pending suspend W onViewTypeUpdate() { foreground re-entered }`() { // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() - val bgTimeseries = DefaultTimeseriesCollector( - pipelines = listOf(pipelineA, pipelineB), - internalLogger = mockInternalLogger, - collectInBackground = true, - scheduledExecutorService = mockExecutor - ) - bgTimeseries.onSessionStart() - bgTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onSessionStart() + testedTimeseries.onViewTypeUpdate(RumViewType.NONE) // When - runnableA.run() + testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) - // Then — sample taken even in background - verify(mockReaderA).read() + // Then + verify(mockScheduledFuture).cancel(false) } @Test - fun `M resume scheduling W onViewTypeUpdate() { background → foreground }`() { + fun `M schedule suspend once W onViewTypeUpdate() { repeated non-foreground updates }`() { // Given testedTimeseries.onSessionStart() - // Transition to background: suspends chains + + // When + testedTimeseries.onViewTypeUpdate(RumViewType.NONE) testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - runnableA.run() // State is already SUSPENDED; tick exits without reschedule - val schedulesAfterSuspend = 1 // only the one from start() + testedTimeseries.onViewTypeUpdate(RumViewType.NONE) - // When — app returns to foreground + // Then + verify(mockExecutor).schedule( + any(), + eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), + eq(TimeUnit.MILLISECONDS) + ) + } + + @Test + fun `M keep sampling chain W stale suspend fires { foreground re-entered then left }`() { + // Given + testedTimeseries.onSessionStart() + testedTimeseries.onViewTypeUpdate(RumViewType.NONE) + val staleSuspend = captureScheduledSuspendRunnable() testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) + val currentRunnableA = captureLastScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + + // When — the suspend from the first exit fires against a generation that moved on + staleSuspend.run() + currentRunnableA.run() - // Then — scheduling resumed (one new schedule per pipeline) - verify(mockExecutor, times(schedulesAfterSuspend + 1)) + // Then — nothing flushed, and the live chain keeps rescheduling + verify(mockDataWriter, never()).write(any(), any(), any()) + verify(mockReaderA, never()).read() + verify(mockExecutor, times(3)) .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) } @Test - fun `M not sample W stale tick fires after resume { old generation tick self-terminates }`(forge: Forge) { - // Regression: when pipeline B's tick (long interval) is still pending at the moment - // resumeSampling() fires, it must self-terminate rather than duplicate the chain. - // - // Given - whenever(mockReaderB.read()) doReturn forge.getForgery>() + fun `M resume scheduling W onViewTypeUpdate() { background to foreground }`() { + // Given — the deferred suspend fired, so the next tick dies without rescheduling testedTimeseries.onSessionStart() - - // Pipeline A suspends the instance (short interval fires first in background) testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - val oldRunnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - val oldRunnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) - oldRunnableA.run() // State is already SUSPENDED (set by onViewTypeUpdate); B's tick is still queued + runScheduledSuspend() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() + verify(mockExecutor, times(1)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) - // Resume creates a new generation and schedules fresh ticks for both pipelines + // When — app returns to foreground testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) - // When — B's old (stale) runnable fires despite the new generation - oldRunnableB.run() - - // Then — stale tick must not sample and must not reschedule - verify(mockReaderB, never()).read() - // Total B schedules: 1 from start() + 1 from resumeSampling = 2; old tick adds nothing + // Then — scheduling resumed, one new schedule per pipeline + verify(mockExecutor, times(2)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) verify(mockExecutor, times(2)) .schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) } @Test - fun `M not sample or reschedule W stale tick fires { different generation, state is RUNNING }`() { - // A stale tick (old generation) must self-terminate via the generation check - // even when state is currently RUNNING. Ticks never write state. + fun `M not sample nor reschedule W stale tick fires { new generation is running }`() { + // Regression: a tick from the generation that was alive before the suspend must + // self-terminate on the generation check, even though the state is running again. // // Given testedTimeseries.onSessionStart() testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - val oldRunnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) - // Resume: state = RUNNING, gen = 2; A and B each get a new schedule + runScheduledSuspend() + val staleRunnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) + // Resume: a fresh generation is running; A and B each get a new schedule testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) - // When — B's stale gen-1 tick fires while state is RUNNING - oldRunnableB.run() + // When — B's stale tick fires + staleRunnableB.run() // Then — stale tick neither samples nor produces an extra schedule verify(mockReaderB, never()).read() - // B schedules: 1 from start() + 1 from resume = 2; stale tick adds nothing verify(mockExecutor, times(2)) .schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) } + private fun createCollector( + initialViewType: RumViewType, + pipelines: List> = listOf(pipelineA, pipelineB) + ) = DefaultTimeseriesCollector( + pipelines = pipelines, + internalLogger = mockInternalLogger, + scheduledExecutorService = mockExecutor, + currentViewType = initialViewType + ) + + private fun runScheduledSuspend() { + captureScheduledSuspendRunnable().run() + } + + private fun captureScheduledSuspendRunnable(): Runnable { + val captor = argumentCaptor() + verify(mockExecutor, atLeastOnce()) + .schedule(captor.capture(), eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), eq(TimeUnit.MILLISECONDS)) + return captor.lastValue + } + + private fun captureLastScheduledRunnableForInterval(intervalMs: Long): Runnable { + val captor = argumentCaptor() + verify(mockExecutor, atLeastOnce()).schedule(captor.capture(), eq(intervalMs), eq(TimeUnit.MILLISECONDS)) + return captor.lastValue + } + private fun captureScheduledRunnableForInterval(intervalMs: Long): Runnable { val captor = argumentCaptor() verify(mockExecutor).schedule(captor.capture(), eq(intervalMs), eq(TimeUnit.MILLISECONDS)) diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt index 3365add0a7..44c041ba85 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt @@ -63,22 +63,4 @@ internal class TimeseriesConfigurationTest { assertThat(config.bufferSize).isEqualTo(fakeBufferSize) assertThat(config.intervalMs).isEqualTo(fakeIntervalMs) } - - @Test - fun `M default collectInBackground to false W built with no args`() { - // When - val config = TimeseriesConfiguration.Builder().build() - - // Then - assertThat(config.collectInBackground).isFalse() - } - - @Test - fun `M store collectInBackground W setCollectInBackground true`() { - // When - val config = TimeseriesConfiguration.Builder().collectInBackground(true).build() - - // Then - assertThat(config.collectInBackground).isTrue() - } } From 1c35566b918eaa69bb0bad2b91c4d7be6c696f3f Mon Sep 17 00:00:00 2001 From: Timur Valeev Date: Fri, 14 Aug 2026 14:39:16 +0100 Subject: [PATCH 3/4] RUM-17613 Build timeseries events from the shared RUM schema Derive the CPU and memory timeseries schemas from _common-schema.json and replace the hand-written JSON serializers with typed event factories that populate the full common event shape (os, device, connectivity, dd, ddtags). Restrict collection through TimeseriesConfiguration.collectOnly. Ref: RUM-17613 --- detekt_custom_safe_calls_third_party.yml | 2 + features/dd-sdk-android-rum/api/apiSurface | 632 ++++- .../api/dd-sdk-android-rum.api | 2263 ++++++++++++++--- .../src/main/json/rum/_common-schema.json | 39 +- .../main/json/rum/timeseries-cpu-schema.json | 194 +- .../json/rum/timeseries-memory-schema.json | 206 +- .../datadog/android/rum/RumConfiguration.kt | 14 +- .../android/rum/internal/RumFeature.kt | 84 +- .../android/rum/internal/RumSessionTypeExt.kt | 16 +- .../rum/internal/domain/RumDataWriter.kt | 4 + .../internal/domain/event/RumEventMapper.kt | 4 + .../domain/event/RumEventSerializer.kt | 8 + .../rum/internal/domain/scope/RumEventExt.kt | 230 ++ .../internal/domain/scope/RumSessionScope.kt | 14 +- .../rum/internal/domain/scope/RumViewScope.kt | 14 +- .../timeseries/DefaultTimeseriesCollector.kt | 67 +- .../DefaultTimeseriesCollectorFactory.kt | 112 +- .../rum/internal/timeseries/Pipeline.kt | 51 +- .../timeseries/TimeseriesCollector.kt | 9 +- .../timeseries/factory/CpuEventFactory.kt | 111 + .../timeseries/factory/EventFactory.kt | 22 + .../timeseries/factory/MemoryEventFactory.kt | 124 + .../timeseries/provider/CpuDatapointReader.kt | 13 +- .../timeseries/provider/DataPointsReader.kt | 2 +- .../serializer/CpuEventSerializer.kt | 47 - .../serializer/MemoryEventSerializer.kt | 60 - ...nSerializer.kt => TimeseriesAttributes.kt} | 8 - .../rum/timeseries/TimeseriesConfiguration.kt | 44 +- .../android/rum/timeseries/TimeseriesType.kt | 19 + .../rum/RumConfigurationBuilderTest.kt | 30 +- .../android/rum/assertj/ActionEventAssert.kt | 24 +- .../android/rum/assertj/ErrorEventAssert.kt | 24 +- .../rum/assertj/LongTaskEventAssert.kt | 8 +- .../rum/assertj/ResourceEventAssert.kt | 12 +- .../rum/assertj/TimeseriesCpuEventAssert.kt | 116 - .../rum/assertj/VitalAppLaunchEventAssert.kt | 12 +- .../android/rum/assertj/VitalEventAssert.kt | 12 +- .../android/rum/internal/RumFeatureTest.kt | 114 +- .../rum/internal/RumSessionTypeExtTest.kt | 19 +- .../rum/internal/domain/RumDataWriterTest.kt | 26 + .../domain/event/RumEventMapperTest.kt | 19 + .../domain/event/RumEventSerializerTest.kt | 77 +- ...pplicationScopeAttributePropagationTest.kt | 11 +- .../domain/scope/RumApplicationScopeTest.kt | 64 +- .../internal/domain/scope/RumEventExtTest.kt | 135 + ...RumSessionScopeAttributePropagationTest.kt | 11 +- .../domain/scope/RumSessionScopeTest.kt | 396 +-- .../internal/domain/scope/RumViewScopeTest.kt | 4 +- .../rum/internal/timeseries/BufferTest.kt | 15 +- .../DefaultTimeseriesCollectorFactoryTest.kt | 285 ++- .../DefaultTimeseriesCollectorTest.kt | 488 ++-- .../rum/internal/timeseries/PipelineTest.kt | 292 ++- .../rum/internal/timeseries/csv/CSVReader.kt | 3 - .../internal/timeseries/csv/CsvCollector.kt | 118 +- .../csv/TimeseriesCollectorEndToEndTest.kt | 245 +- .../timeseries/factory/CpuEventFactoryTest.kt | 469 ++++ .../factory/MemoryEventFactoryTest.kt | 501 ++++ .../provider/CpuDatapointReaderTest.kt | 18 +- .../provider/VitalReaderWrapperTest.kt | 22 +- .../serializer/CpuEventSerializerTest.kt | 147 -- .../serializer/MemoryEventSerializerTest.kt | 177 -- .../rum/internal/vitals/CpuStatReaderTest.kt | 8 +- .../timeseries/TimeseriesConfigurationTest.kt | 66 - .../TimeseriesConfigurationTests.kt | 49 + .../timeseries/expected_cpu_batch1.json | 71 +- .../timeseries/expected_cpu_batch2.json | 71 +- .../timeseries/expected_memory_batch1.json | 79 +- .../timeseries/expected_memory_batch2.json | 79 +- .../rum/assertj/TimeseriesCpuEventAssert.kt | 169 ++ .../assertj/TimeseriesMemoryEventAssert.kt | 203 ++ 70 files changed, 6510 insertions(+), 2592 deletions(-) create mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactory.kt create mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/EventFactory.kt create mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactory.kt delete mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializer.kt delete mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializer.kt rename features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/{JsonSerializer.kt => TimeseriesAttributes.kt} (61%) create mode 100644 features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesType.kt delete mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt create mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactoryTest.kt create mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactoryTest.kt delete mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializerTest.kt delete mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializerTest.kt delete mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt create mode 100644 features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTests.kt create mode 100644 features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt create mode 100644 features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesMemoryEventAssert.kt diff --git a/detekt_custom_safe_calls_third_party.yml b/detekt_custom_safe_calls_third_party.yml index b1603c68dc..a6501cd78a 100644 --- a/detekt_custom_safe_calls_third_party.yml +++ b/detekt_custom_safe_calls_third_party.yml @@ -758,6 +758,8 @@ datadog: - "kotlin.collections.listOf(com.datadog.android.rum.model.ErrorEvent.Interface)" - "kotlin.collections.listOf(com.datadog.android.rum.model.LongTaskEvent.Interface)" - "kotlin.collections.listOf(com.datadog.android.rum.model.ResourceEvent.Interface)" + - "kotlin.collections.listOf(com.datadog.android.rum.model.TimeseriesCpuEvent.Interface)" + - "kotlin.collections.listOf(com.datadog.android.rum.model.TimeseriesMemoryEvent.Interface)" - "kotlin.collections.listOf(com.datadog.android.rum.model.ViewEvent.Interface)" - "kotlin.collections.listOf(com.datadog.android.rum.model.VitalAppLaunchEvent.Interface)" - "kotlin.collections.listOf(com.datadog.android.rum.model.VitalOperationStepEvent.Interface)" diff --git a/features/dd-sdk-android-rum/api/apiSurface b/features/dd-sdk-android-rum/api/apiSurface index d218d217cf..de6d4615ae 100644 --- a/features/dd-sdk-android-rum/api/apiSurface +++ b/features/dd-sdk-android-rum/api/apiSurface @@ -90,7 +90,7 @@ data class com.datadog.android.rum.RumConfiguration fun setSlowFramesConfiguration(com.datadog.android.rum.configuration.SlowFramesConfiguration?): Builder fun trackAnonymousUser(Boolean): Builder fun setAppStartupActivityPredicate(com.datadog.android.rum.startup.AppStartupActivityPredicate): Builder - fun setTimeseriesConfiguration(com.datadog.android.rum.timeseries.TimeseriesConfiguration?): Builder + fun setTimeseriesConfiguration(com.datadog.android.rum.timeseries.TimeseriesConfiguration): Builder fun build(): RumConfiguration enum com.datadog.android.rum.RumErrorSource - NETWORK @@ -312,11 +312,13 @@ interface com.datadog.android.rum.startup.AppStartupActivityPredicate fun shouldTrackStartup(android.app.Activity): Boolean class com.datadog.android.rum.timeseries.TimeseriesConfiguration class Builder - fun setBufferSize(Int): Builder - fun setIntervalMs(Long): Builder + fun collectOnly(TimeseriesType): Builder fun build(): TimeseriesConfiguration companion object val DEFAULT: TimeseriesConfiguration +enum com.datadog.android.rum.timeseries.TimeseriesType + - CPU + - MEMORY open class com.datadog.android.rum.tracking.AcceptAllActivities : ComponentPredicate override fun accept(android.app.Activity): Boolean override fun getViewName(android.app.Activity): String? @@ -400,7 +402,7 @@ class com.datadog.android.sqlite.DatadogDatabaseErrorHandler : android.database. constructor(String? = null, android.database.DatabaseErrorHandler = DefaultDatabaseErrorHandler()) override fun onCorruption(android.database.sqlite.SQLiteDatabase) data class com.datadog.android.rum.model.ActionEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ActionEventSession, ActionEventSource? = null, ActionEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Container? = null, ActionEventAction) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ActionEventSession, ActionEventSource? = null, ActionEventView? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Container? = null, ActionEventAction) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -436,6 +438,12 @@ data class com.datadog.android.rum.model.ActionEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(Status, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -485,8 +493,14 @@ data class com.datadog.android.rum.model.ActionEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Container - constructor(ContainerView, ActionEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -516,7 +530,7 @@ data class com.datadog.android.rum.model.ActionEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -592,7 +606,7 @@ data class com.datadog.android.rum.model.ActionEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -648,6 +662,22 @@ data class com.datadog.android.rum.model.ActionEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum ActionEventActionType constructor(kotlin.String) - CUSTOM @@ -701,7 +731,7 @@ data class com.datadog.android.rum.model.ActionEvent companion object fun fromJson(kotlin.String): Type data class com.datadog.android.rum.model.ErrorEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ErrorEventSession, ErrorEventSource? = null, ErrorEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Action? = null, Container? = null, Error, Freeze? = null, Context? = null) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ErrorEventSession, ErrorEventSource? = null, ErrorEventView? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Action? = null, Container? = null, Error, Freeze? = null, Context? = null) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -737,6 +767,12 @@ data class com.datadog.android.rum.model.ErrorEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(ConnectivityStatus, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -786,6 +822,12 @@ data class com.datadog.android.rum.model.ErrorEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Action constructor(kotlin.collections.List) fun toJson(): com.google.gson.JsonElement @@ -793,7 +835,7 @@ data class com.datadog.android.rum.model.ErrorEvent fun fromJson(kotlin.String): Action fun fromJsonObject(com.google.gson.JsonObject): Action data class Container - constructor(ContainerView, ErrorEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -829,7 +871,7 @@ data class com.datadog.android.rum.model.ErrorEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -899,7 +941,7 @@ data class com.datadog.android.rum.model.ErrorEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -955,6 +997,22 @@ data class com.datadog.android.rum.model.ErrorEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum ErrorSource constructor(kotlin.String) - NETWORK @@ -1082,7 +1140,7 @@ data class com.datadog.android.rum.model.ErrorEvent companion object fun fromJson(kotlin.String): ProviderType data class com.datadog.android.rum.model.LongTaskEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, LongTaskEventSession, LongTaskEventSource? = null, LongTaskEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Action? = null, Container? = null, LongTask) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, LongTaskEventSession, LongTaskEventSource? = null, LongTaskEventView? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Action? = null, Container? = null, LongTask) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -1118,6 +1176,12 @@ data class com.datadog.android.rum.model.LongTaskEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(ConnectivityStatus, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -1167,6 +1231,12 @@ data class com.datadog.android.rum.model.LongTaskEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Action constructor(kotlin.collections.List) fun toJson(): com.google.gson.JsonElement @@ -1174,7 +1244,7 @@ data class com.datadog.android.rum.model.LongTaskEvent fun fromJson(kotlin.String): Action fun fromJsonObject(com.google.gson.JsonObject): Action data class Container - constructor(ContainerView, LongTaskEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -1204,7 +1274,7 @@ data class com.datadog.android.rum.model.LongTaskEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -1238,7 +1308,7 @@ data class com.datadog.android.rum.model.LongTaskEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -1294,6 +1364,22 @@ data class com.datadog.android.rum.model.LongTaskEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum EntryType constructor(kotlin.String) - LONG_TASK @@ -1350,7 +1436,7 @@ data class com.datadog.android.rum.model.LongTaskEvent companion object fun fromJson(kotlin.String): InvokerType data class com.datadog.android.rum.model.ResourceEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ResourceEventSession, ResourceEventSource? = null, ResourceEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Action? = null, Container? = null, Resource) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ResourceEventSession, ResourceEventSource? = null, ResourceEventView? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Action? = null, Container? = null, Resource) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -1386,6 +1472,12 @@ data class com.datadog.android.rum.model.ResourceEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(Status, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -1435,6 +1527,12 @@ data class com.datadog.android.rum.model.ResourceEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Action constructor(kotlin.collections.List) fun toJson(): com.google.gson.JsonElement @@ -1442,7 +1540,7 @@ data class com.datadog.android.rum.model.ResourceEvent fun fromJson(kotlin.String): Action fun fromJsonObject(com.google.gson.JsonObject): Action data class Container - constructor(ContainerView, ResourceEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -1472,7 +1570,7 @@ data class com.datadog.android.rum.model.ResourceEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -1595,7 +1693,7 @@ data class com.datadog.android.rum.model.ResourceEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -1651,6 +1749,22 @@ data class com.datadog.android.rum.model.ResourceEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum ResourceType constructor(kotlin.String) - DOCUMENT @@ -1743,30 +1857,103 @@ data class com.datadog.android.rum.model.ResourceEvent companion object fun fromJson(kotlin.String): OperationType data class com.datadog.android.rum.model.TimeseriesCpuEvent - constructor(Dd, Application, Session, Source, kotlin.Long, kotlin.String? = null, kotlin.String? = null, Timeseries) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, TimeseriesCpuEventSession, Source? = null, View? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Timeseries) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): TimeseriesCpuEvent fun fromJsonObject(com.google.gson.JsonObject): TimeseriesCpuEvent - class Dd + data class Application + constructor(kotlin.String, kotlin.String? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Application + fun fromJsonObject(com.google.gson.JsonObject): Application + data class TimeseriesCpuEventSession + constructor(kotlin.String, TimeseriesCpuEventSessionType, kotlin.Boolean? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): TimeseriesCpuEventSession + fun fromJsonObject(com.google.gson.JsonObject): TimeseriesCpuEventSession + data class View + constructor(kotlin.String, kotlin.String? = null, kotlin.String, kotlin.String? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): View + fun fromJsonObject(com.google.gson.JsonObject): View + data class Usr + constructor(kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.MutableMap = mutableMapOf()) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Usr + fun fromJsonObject(com.google.gson.JsonObject): Usr + data class Account + constructor(kotlin.String, kotlin.String? = null, kotlin.collections.MutableMap = mutableMapOf()) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Account + fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab + data class Connectivity + constructor(Status, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Connectivity + fun fromJsonObject(com.google.gson.JsonObject): Connectivity + data class Display + constructor(Viewport? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Display + fun fromJsonObject(com.google.gson.JsonObject): Display + data class Synthetics + constructor(kotlin.String, kotlin.String, kotlin.Boolean? = null, kotlin.collections.MutableMap = mutableMapOf()) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Synthetics + fun fromJsonObject(com.google.gson.JsonObject): Synthetics + data class CiTest + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): CiTest + fun fromJsonObject(com.google.gson.JsonObject): CiTest + data class Os + constructor(kotlin.String, kotlin.String, kotlin.String? = null, kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Os + fun fromJsonObject(com.google.gson.JsonObject): Os + data class Device + constructor(DeviceType? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.List? = null, kotlin.String? = null, kotlin.Number? = null, kotlin.Boolean? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.Boolean? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Device + fun fromJsonObject(com.google.gson.JsonObject): Device + data class Dd + constructor(DdSession? = null, Configuration? = null, kotlin.String? = null, kotlin.String? = null) val formatVersion: kotlin.Long fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Dd fun fromJsonObject(com.google.gson.JsonObject): Dd - data class Application - constructor(kotlin.String) + data class Context + constructor(kotlin.collections.MutableMap = mutableMapOf()) fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Application - fun fromJsonObject(com.google.gson.JsonObject): Application - data class Session - constructor(kotlin.String, Type) + fun fromJson(kotlin.String): Context + fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Session - fun fromJsonObject(com.google.gson.JsonObject): Session + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Timeseries constructor(kotlin.String, kotlin.Long, kotlin.Long, Data) val name: kotlin.String @@ -1775,6 +1962,30 @@ data class com.datadog.android.rum.model.TimeseriesCpuEvent companion object fun fromJson(kotlin.String): Timeseries fun fromJsonObject(com.google.gson.JsonObject): Timeseries + data class Cellular + constructor(kotlin.String? = null, kotlin.String? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Cellular + fun fromJsonObject(com.google.gson.JsonObject): Cellular + data class Viewport + constructor(kotlin.Number, kotlin.Number) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Viewport + fun fromJsonObject(com.google.gson.JsonObject): Viewport + data class DdSession + constructor(Plan? = null, SessionPrecondition? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): DdSession + fun fromJsonObject(com.google.gson.JsonObject): DdSession + data class Configuration + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Configuration + fun fromJsonObject(com.google.gson.JsonObject): Configuration data class Data constructor(kotlin.collections.List, Values) fun toJson(): com.google.gson.JsonElement @@ -1798,43 +2009,179 @@ data class com.datadog.android.rum.model.TimeseriesCpuEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP + - MAUI fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Source - enum Type + enum TimeseriesCpuEventSessionType constructor(kotlin.String) - USER - SYNTHETICS - CI_TEST fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Type + fun fromJson(kotlin.String): TimeseriesCpuEventSessionType + enum Status + constructor(kotlin.String) + - CONNECTED + - NOT_CONNECTED + - MAYBE + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Status + enum Interface + constructor(kotlin.String) + - BLUETOOTH + - CELLULAR + - ETHERNET + - WIFI + - WIMAX + - MIXED + - OTHER + - UNKNOWN + - NONE + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Interface + enum EffectiveType + constructor(kotlin.String) + - SLOW_2G + - `2G` + - `3G` + - `4G` + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): EffectiveType + enum DeviceType + constructor(kotlin.String) + - MOBILE + - DESKTOP + - TABLET + - TV + - GAMING_CONSOLE + - BOT + - OTHER + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): DeviceType + enum Plan + constructor(kotlin.Number) + - PLAN_1 + - PLAN_2 + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Plan + enum SessionPrecondition + constructor(kotlin.String) + - USER_APP_LAUNCH + - INACTIVITY_TIMEOUT + - MAX_DURATION + - BACKGROUND_LAUNCH + - PREWARM + - FROM_NON_INTERACTIVE_SESSION + - EXPLICIT_STOP + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): SessionPrecondition data class com.datadog.android.rum.model.TimeseriesMemoryEvent - constructor(Dd, Application, Session, Source, kotlin.Long, kotlin.String? = null, kotlin.String? = null, Timeseries) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, TimeseriesMemoryEventSession, Source? = null, View? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Timeseries) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): TimeseriesMemoryEvent fun fromJsonObject(com.google.gson.JsonObject): TimeseriesMemoryEvent - class Dd + data class Application + constructor(kotlin.String, kotlin.String? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Application + fun fromJsonObject(com.google.gson.JsonObject): Application + data class TimeseriesMemoryEventSession + constructor(kotlin.String, TimeseriesMemoryEventSessionType, kotlin.Boolean? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): TimeseriesMemoryEventSession + fun fromJsonObject(com.google.gson.JsonObject): TimeseriesMemoryEventSession + data class View + constructor(kotlin.String, kotlin.String? = null, kotlin.String, kotlin.String? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): View + fun fromJsonObject(com.google.gson.JsonObject): View + data class Usr + constructor(kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.MutableMap = mutableMapOf()) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Usr + fun fromJsonObject(com.google.gson.JsonObject): Usr + data class Account + constructor(kotlin.String, kotlin.String? = null, kotlin.collections.MutableMap = mutableMapOf()) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Account + fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab + data class Connectivity + constructor(Status, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Connectivity + fun fromJsonObject(com.google.gson.JsonObject): Connectivity + data class Display + constructor(Viewport? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Display + fun fromJsonObject(com.google.gson.JsonObject): Display + data class Synthetics + constructor(kotlin.String, kotlin.String, kotlin.Boolean? = null, kotlin.collections.MutableMap = mutableMapOf()) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Synthetics + fun fromJsonObject(com.google.gson.JsonObject): Synthetics + data class CiTest + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): CiTest + fun fromJsonObject(com.google.gson.JsonObject): CiTest + data class Os + constructor(kotlin.String, kotlin.String, kotlin.String? = null, kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Os + fun fromJsonObject(com.google.gson.JsonObject): Os + data class Device + constructor(DeviceType? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.collections.List? = null, kotlin.String? = null, kotlin.Number? = null, kotlin.Boolean? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.Boolean? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Device + fun fromJsonObject(com.google.gson.JsonObject): Device + data class Dd + constructor(DdSession? = null, Configuration? = null, kotlin.String? = null, kotlin.String? = null) val formatVersion: kotlin.Long fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Dd fun fromJsonObject(com.google.gson.JsonObject): Dd - data class Application - constructor(kotlin.String) + data class Context + constructor(kotlin.collections.MutableMap = mutableMapOf()) fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Application - fun fromJsonObject(com.google.gson.JsonObject): Application - data class Session - constructor(kotlin.String, Type) + fun fromJson(kotlin.String): Context + fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Session - fun fromJsonObject(com.google.gson.JsonObject): Session + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Timeseries constructor(kotlin.String, kotlin.Long, kotlin.Long, Data) val name: kotlin.String @@ -1843,6 +2190,30 @@ data class com.datadog.android.rum.model.TimeseriesMemoryEvent companion object fun fromJson(kotlin.String): Timeseries fun fromJsonObject(com.google.gson.JsonObject): Timeseries + data class Cellular + constructor(kotlin.String? = null, kotlin.String? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Cellular + fun fromJsonObject(com.google.gson.JsonObject): Cellular + data class Viewport + constructor(kotlin.Number, kotlin.Number) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Viewport + fun fromJsonObject(com.google.gson.JsonObject): Viewport + data class DdSession + constructor(Plan? = null, SessionPrecondition? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): DdSession + fun fromJsonObject(com.google.gson.JsonObject): DdSession + data class Configuration + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Configuration + fun fromJsonObject(com.google.gson.JsonObject): Configuration data class Data constructor(kotlin.collections.List, Values) fun toJson(): com.google.gson.JsonElement @@ -1866,20 +2237,83 @@ data class com.datadog.android.rum.model.TimeseriesMemoryEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP + - MAUI fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Source - enum Type + enum TimeseriesMemoryEventSessionType constructor(kotlin.String) - USER - SYNTHETICS - CI_TEST fun toJson(): com.google.gson.JsonElement companion object - fun fromJson(kotlin.String): Type + fun fromJson(kotlin.String): TimeseriesMemoryEventSessionType + enum Status + constructor(kotlin.String) + - CONNECTED + - NOT_CONNECTED + - MAYBE + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Status + enum Interface + constructor(kotlin.String) + - BLUETOOTH + - CELLULAR + - ETHERNET + - WIFI + - WIMAX + - MIXED + - OTHER + - UNKNOWN + - NONE + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Interface + enum EffectiveType + constructor(kotlin.String) + - SLOW_2G + - `2G` + - `3G` + - `4G` + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): EffectiveType + enum DeviceType + constructor(kotlin.String) + - MOBILE + - DESKTOP + - TABLET + - TV + - GAMING_CONSOLE + - BOT + - OTHER + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): DeviceType + enum Plan + constructor(kotlin.Number) + - PLAN_1 + - PLAN_2 + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Plan + enum SessionPrecondition + constructor(kotlin.String) + - USER_APP_LAUNCH + - INACTIVITY_TIMEOUT + - MAX_DURATION + - BACKGROUND_LAUNCH + - PREWARM + - FROM_NON_INTERACTIVE_SESSION + - EXPLICIT_STOP + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): SessionPrecondition data class com.datadog.android.rum.model.ViewEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ViewEventSession, ViewEventSource? = null, ViewEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Container? = null, Context? = null, Privacy? = null) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, ViewEventSession, ViewEventSource? = null, ViewEventView, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Container? = null, Context? = null, Privacy? = null) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -1915,6 +2349,12 @@ data class com.datadog.android.rum.model.ViewEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(ConnectivityStatus, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -1964,8 +2404,14 @@ data class com.datadog.android.rum.model.ViewEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Container - constructor(ContainerView, ViewEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -2079,7 +2525,7 @@ data class com.datadog.android.rum.model.ViewEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.Boolean? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null, kotlin.Boolean? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -2179,7 +2625,7 @@ data class com.datadog.android.rum.model.ViewEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -2248,6 +2694,22 @@ data class com.datadog.android.rum.model.ViewEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum ReplayLevel constructor(kotlin.String) - ALLOW @@ -2304,7 +2766,7 @@ data class com.datadog.android.rum.model.ViewEvent companion object fun fromJson(kotlin.String): ErrorReason data class com.datadog.android.rum.model.VitalAppLaunchEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, VitalAppLaunchEventSession, VitalAppLaunchEventSource? = null, VitalAppLaunchEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Container? = null, Vital) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, VitalAppLaunchEventSession, VitalAppLaunchEventSource? = null, VitalAppLaunchEventView? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Container? = null, Vital) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -2340,6 +2802,12 @@ data class com.datadog.android.rum.model.VitalAppLaunchEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(ConnectivityStatus, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -2389,8 +2857,14 @@ data class com.datadog.android.rum.model.VitalAppLaunchEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Container - constructor(ContainerView, VitalAppLaunchEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -2421,7 +2895,7 @@ data class com.datadog.android.rum.model.VitalAppLaunchEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -2449,7 +2923,7 @@ data class com.datadog.android.rum.model.VitalAppLaunchEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -2505,6 +2979,22 @@ data class com.datadog.android.rum.model.VitalAppLaunchEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum AppLaunchMetric constructor(kotlin.String) - TTID @@ -2557,7 +3047,7 @@ data class com.datadog.android.rum.model.VitalAppLaunchEvent companion object fun fromJson(kotlin.String): ErrorReason data class com.datadog.android.rum.model.VitalOperationStepEvent - constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, VitalOperationStepEventSession, VitalOperationStepEventSource? = null, VitalOperationStepEventView, Usr? = null, Account? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Container? = null, Vital) + constructor(kotlin.Long, Application, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, kotlin.String? = null, VitalOperationStepEventSession, VitalOperationStepEventSource? = null, VitalOperationStepEventView? = null, Usr? = null, Account? = null, Tab? = null, Connectivity? = null, Display? = null, Synthetics? = null, CiTest? = null, Os? = null, Device? = null, Dd, Context? = null, Stream? = null, Container? = null, Vital) val type: kotlin.String fun toJson(): com.google.gson.JsonElement companion object @@ -2593,6 +3083,12 @@ data class com.datadog.android.rum.model.VitalOperationStepEvent companion object fun fromJson(kotlin.String): Account fun fromJsonObject(com.google.gson.JsonObject): Account + data class Tab + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Tab + fun fromJsonObject(com.google.gson.JsonObject): Tab data class Connectivity constructor(ConnectivityStatus, kotlin.collections.List? = null, EffectiveType? = null, Cellular? = null) fun toJson(): com.google.gson.JsonElement @@ -2642,8 +3138,14 @@ data class com.datadog.android.rum.model.VitalOperationStepEvent companion object fun fromJson(kotlin.String): Context fun fromJsonObject(com.google.gson.JsonObject): Context + data class Stream + constructor(kotlin.String) + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): Stream + fun fromJsonObject(com.google.gson.JsonObject): Stream data class Container - constructor(ContainerView, VitalOperationStepEventSource) + constructor(ContainerView, ContainerSource) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Container @@ -2674,7 +3176,7 @@ data class com.datadog.android.rum.model.VitalOperationStepEvent fun fromJson(kotlin.String): DdSession fun fromJsonObject(com.google.gson.JsonObject): DdSession data class Configuration - constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null) + constructor(kotlin.Number, kotlin.Number? = null, kotlin.Number? = null, kotlin.Number? = null, kotlin.collections.List? = null) fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): Configuration @@ -2702,7 +3204,7 @@ data class com.datadog.android.rum.model.VitalOperationStepEvent - UNITY - KOTLIN_MULTIPLATFORM - ELECTRON - - RUM_CPP + - CPP - MAUI fun toJson(): com.google.gson.JsonElement companion object @@ -2758,6 +3260,22 @@ data class com.datadog.android.rum.model.VitalOperationStepEvent fun toJson(): com.google.gson.JsonElement companion object fun fromJson(kotlin.String): DeviceType + enum ContainerSource + constructor(kotlin.String) + - ANDROID + - IOS + - BROWSER + - FLUTTER + - REACT_NATIVE + - ROKU + - UNITY + - KOTLIN_MULTIPLATFORM + - ELECTRON + - RUM_CPP + - MAUI + fun toJson(): com.google.gson.JsonElement + companion object + fun fromJson(kotlin.String): ContainerSource enum StepType constructor(kotlin.String) - START diff --git a/features/dd-sdk-android-rum/api/dd-sdk-android-rum.api b/features/dd-sdk-android-rum/api/dd-sdk-android-rum.api index df7bbe50c8..a0e214e7d9 100644 --- a/features/dd-sdk-android-rum/api/dd-sdk-android-rum.api +++ b/features/dd-sdk-android-rum/api/dd-sdk-android-rum.api @@ -517,23 +517,25 @@ public final class com/datadog/android/rum/metric/networksettled/TimeBasedInitia public final class com/datadog/android/rum/model/ActionEvent { public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Companion; - public fun (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;)V - public synthetic fun (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Tab;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Stream;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;)V + public synthetic fun (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Tab;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Stream;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventView; public final fun component11 ()Lcom/datadog/android/rum/model/ActionEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/ActionEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/ActionEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/ActionEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/ActionEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/ActionEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/ActionEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/ActionEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/ActionEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/ActionEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/ActionEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/ActionEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/ActionEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/ActionEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/ActionEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/ActionEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/ActionEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/ActionEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/ActionEvent$Container; - public final fun component22 ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction; + public final fun component20 ()Lcom/datadog/android/rum/model/ActionEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/ActionEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/ActionEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/ActionEvent$Container; + public final fun component24 ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -541,8 +543,8 @@ public final class com/datadog/android/rum/model/ActionEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; - public final fun copy (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;)Lcom/datadog/android/rum/model/ActionEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent;JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent; + public final fun copy (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Tab;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Stream;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;)Lcom/datadog/android/rum/model/ActionEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent;JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Account;Lcom/datadog/android/rum/model/ActionEvent$Tab;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Stream;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent; @@ -564,7 +566,9 @@ public final class com/datadog/android/rum/model/ActionEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/ActionEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/ActionEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/ActionEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/ActionEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -719,6 +723,7 @@ public final class com/datadog/android/rum/model/ActionEvent$ActionEventSessionT public final class com/datadog/android/rum/model/ActionEvent$ActionEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; + public static final field CPP Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; @@ -727,7 +732,6 @@ public final class com/datadog/android/rum/model/ActionEvent$ActionEventSource : public static final field MAUI Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final field ROKU Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final field UNITY Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -845,18 +849,20 @@ public final class com/datadog/android/rum/model/ActionEvent$Companion { public final class com/datadog/android/rum/model/ActionEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/ActionEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/ActionEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getTraceSampleRate ()Ljava/lang/Number; @@ -899,15 +905,15 @@ public final class com/datadog/android/rum/model/ActionEvent$Connectivity$Compan public final class com/datadog/android/rum/model/ActionEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/ActionEvent$ContainerView;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;)V + public fun (Lcom/datadog/android/rum/model/ActionEvent$ContainerView;Lcom/datadog/android/rum/model/ActionEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/ActionEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; - public final fun copy (Lcom/datadog/android/rum/model/ActionEvent$ContainerView;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;)Lcom/datadog/android/rum/model/ActionEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ContainerView;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/ActionEvent$ContainerView;Lcom/datadog/android/rum/model/ActionEvent$ContainerSource;)Lcom/datadog/android/rum/model/ActionEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ContainerView;Lcom/datadog/android/rum/model/ActionEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/ActionEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -919,6 +925,29 @@ public final class com/datadog/android/rum/model/ActionEvent$Container$Companion public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Container; } +public final class com/datadog/android/rum/model/ActionEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/ActionEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/ActionEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -1414,6 +1443,26 @@ public final class com/datadog/android/rum/model/ActionEvent$Status$Companion { public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Status; } +public final class com/datadog/android/rum/model/ActionEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ActionEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Stream; +} + public final class com/datadog/android/rum/model/ActionEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -1441,6 +1490,26 @@ public final class com/datadog/android/rum/model/ActionEvent$Synthetics$Companio public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Synthetics; } +public final class com/datadog/android/rum/model/ActionEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ActionEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ActionEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ActionEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ActionEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ActionEvent$Tab; +} + public final class com/datadog/android/rum/model/ActionEvent$Type : java/lang/Enum { public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Type$Companion; public static final field DEAD_CLICK Lcom/datadog/android/rum/model/ActionEvent$Type; @@ -1512,26 +1581,28 @@ public final class com/datadog/android/rum/model/ActionEvent$Viewport$Companion public final class com/datadog/android/rum/model/ErrorEvent { public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Companion; - public fun (JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;)V - public synthetic fun (JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Tab;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Stream;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;)V + public synthetic fun (JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Tab;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Stream;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView; public final fun component11 ()Lcom/datadog/android/rum/model/ErrorEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/ErrorEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/ErrorEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/ErrorEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/ErrorEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/ErrorEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/ErrorEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/ErrorEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/ErrorEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/ErrorEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/ErrorEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/ErrorEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/ErrorEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/ErrorEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/ErrorEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/ErrorEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/ErrorEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/ErrorEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/ErrorEvent$Action; - public final fun component22 ()Lcom/datadog/android/rum/model/ErrorEvent$Container; - public final fun component23 ()Lcom/datadog/android/rum/model/ErrorEvent$Error; - public final fun component24 ()Lcom/datadog/android/rum/model/ErrorEvent$Freeze; - public final fun component25 ()Lcom/datadog/android/rum/model/ErrorEvent$Context; + public final fun component20 ()Lcom/datadog/android/rum/model/ErrorEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/ErrorEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/ErrorEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/ErrorEvent$Action; + public final fun component24 ()Lcom/datadog/android/rum/model/ErrorEvent$Container; + public final fun component25 ()Lcom/datadog/android/rum/model/ErrorEvent$Error; + public final fun component26 ()Lcom/datadog/android/rum/model/ErrorEvent$Freeze; + public final fun component27 ()Lcom/datadog/android/rum/model/ErrorEvent$Context; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -1539,8 +1610,8 @@ public final class com/datadog/android/rum/model/ErrorEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; - public final fun copy (JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;)Lcom/datadog/android/rum/model/ErrorEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent;JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent; + public final fun copy (JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Tab;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Stream;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;)Lcom/datadog/android/rum/model/ErrorEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent;JLcom/datadog/android/rum/model/ErrorEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventView;Lcom/datadog/android/rum/model/ErrorEvent$Usr;Lcom/datadog/android/rum/model/ErrorEvent$Account;Lcom/datadog/android/rum/model/ErrorEvent$Tab;Lcom/datadog/android/rum/model/ErrorEvent$Connectivity;Lcom/datadog/android/rum/model/ErrorEvent$Display;Lcom/datadog/android/rum/model/ErrorEvent$Synthetics;Lcom/datadog/android/rum/model/ErrorEvent$CiTest;Lcom/datadog/android/rum/model/ErrorEvent$Os;Lcom/datadog/android/rum/model/ErrorEvent$Device;Lcom/datadog/android/rum/model/ErrorEvent$Dd;Lcom/datadog/android/rum/model/ErrorEvent$Context;Lcom/datadog/android/rum/model/ErrorEvent$Stream;Lcom/datadog/android/rum/model/ErrorEvent$Action;Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$Error;Lcom/datadog/android/rum/model/ErrorEvent$Freeze;Lcom/datadog/android/rum/model/ErrorEvent$Context;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent; @@ -1565,7 +1636,9 @@ public final class com/datadog/android/rum/model/ErrorEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/ErrorEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/ErrorEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/ErrorEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/ErrorEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -1772,18 +1845,20 @@ public final class com/datadog/android/rum/model/ErrorEvent$Companion { public final class com/datadog/android/rum/model/ErrorEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/ErrorEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/ErrorEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getTraceSampleRate ()Ljava/lang/Number; @@ -1841,15 +1916,15 @@ public final class com/datadog/android/rum/model/ErrorEvent$ConnectivityStatus$C public final class com/datadog/android/rum/model/ErrorEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/ErrorEvent$ContainerView;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;)V + public fun (Lcom/datadog/android/rum/model/ErrorEvent$ContainerView;Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/ErrorEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; - public final fun copy (Lcom/datadog/android/rum/model/ErrorEvent$ContainerView;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;)Lcom/datadog/android/rum/model/ErrorEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$ContainerView;Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/ErrorEvent$ContainerView;Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource;)Lcom/datadog/android/rum/model/ErrorEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent$Container;Lcom/datadog/android/rum/model/ErrorEvent$ContainerView;Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/ErrorEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -1861,6 +1936,29 @@ public final class com/datadog/android/rum/model/ErrorEvent$Container$Companion public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Container; } +public final class com/datadog/android/rum/model/ErrorEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/ErrorEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/ErrorEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -2204,6 +2302,7 @@ public final class com/datadog/android/rum/model/ErrorEvent$ErrorEventSessionTyp public final class com/datadog/android/rum/model/ErrorEvent$ErrorEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; + public static final field CPP Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; @@ -2212,7 +2311,6 @@ public final class com/datadog/android/rum/model/ErrorEvent$ErrorEventSource : j public static final field MAUI Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final field ROKU Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final field UNITY Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$ErrorEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -2611,6 +2709,26 @@ public final class com/datadog/android/rum/model/ErrorEvent$SourceType$Companion public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$SourceType; } +public final class com/datadog/android/rum/model/ErrorEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ErrorEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Stream; +} + public final class com/datadog/android/rum/model/ErrorEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -2638,6 +2756,26 @@ public final class com/datadog/android/rum/model/ErrorEvent$Synthetics$Companion public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Synthetics; } +public final class com/datadog/android/rum/model/ErrorEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ErrorEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ErrorEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ErrorEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ErrorEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ErrorEvent$Tab; +} + public final class com/datadog/android/rum/model/ErrorEvent$Thread { public static final field Companion Lcom/datadog/android/rum/model/ErrorEvent$Thread$Companion; public fun (Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V @@ -2719,24 +2857,26 @@ public final class com/datadog/android/rum/model/ErrorEvent$Viewport$Companion { public final class com/datadog/android/rum/model/LongTaskEvent { public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Companion; - public fun (JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;)V - public synthetic fun (JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Tab;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Stream;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;)V + public synthetic fun (JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Tab;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Stream;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView; public final fun component11 ()Lcom/datadog/android/rum/model/LongTaskEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/LongTaskEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/LongTaskEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/LongTaskEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/LongTaskEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/LongTaskEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/LongTaskEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/LongTaskEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/LongTaskEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/LongTaskEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/LongTaskEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/LongTaskEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/LongTaskEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/LongTaskEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/LongTaskEvent$Action; - public final fun component22 ()Lcom/datadog/android/rum/model/LongTaskEvent$Container; - public final fun component23 ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTask; + public final fun component20 ()Lcom/datadog/android/rum/model/LongTaskEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/LongTaskEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/LongTaskEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/LongTaskEvent$Action; + public final fun component24 ()Lcom/datadog/android/rum/model/LongTaskEvent$Container; + public final fun component25 ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTask; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -2744,8 +2884,8 @@ public final class com/datadog/android/rum/model/LongTaskEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; - public final fun copy (JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;)Lcom/datadog/android/rum/model/LongTaskEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent;JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent; + public final fun copy (JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Tab;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Stream;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;)Lcom/datadog/android/rum/model/LongTaskEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent;JLcom/datadog/android/rum/model/LongTaskEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventView;Lcom/datadog/android/rum/model/LongTaskEvent$Usr;Lcom/datadog/android/rum/model/LongTaskEvent$Account;Lcom/datadog/android/rum/model/LongTaskEvent$Tab;Lcom/datadog/android/rum/model/LongTaskEvent$Connectivity;Lcom/datadog/android/rum/model/LongTaskEvent$Display;Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics;Lcom/datadog/android/rum/model/LongTaskEvent$CiTest;Lcom/datadog/android/rum/model/LongTaskEvent$Os;Lcom/datadog/android/rum/model/LongTaskEvent$Device;Lcom/datadog/android/rum/model/LongTaskEvent$Dd;Lcom/datadog/android/rum/model/LongTaskEvent$Context;Lcom/datadog/android/rum/model/LongTaskEvent$Stream;Lcom/datadog/android/rum/model/LongTaskEvent$Action;Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$LongTask;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent; @@ -2768,7 +2908,9 @@ public final class com/datadog/android/rum/model/LongTaskEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/LongTaskEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/LongTaskEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/LongTaskEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -2897,18 +3039,20 @@ public final class com/datadog/android/rum/model/LongTaskEvent$Companion { public final class com/datadog/android/rum/model/LongTaskEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/LongTaskEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/LongTaskEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getTraceSampleRate ()Ljava/lang/Number; @@ -2966,15 +3110,15 @@ public final class com/datadog/android/rum/model/LongTaskEvent$ConnectivityStatu public final class com/datadog/android/rum/model/LongTaskEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;)V + public fun (Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView;Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; - public final fun copy (Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView;Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView;Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent$Container;Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView;Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -2986,6 +3130,29 @@ public final class com/datadog/android/rum/model/LongTaskEvent$Container$Compani public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Container; } +public final class com/datadog/android/rum/model/LongTaskEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/LongTaskEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/LongTaskEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -3341,6 +3508,7 @@ public final class com/datadog/android/rum/model/LongTaskEvent$LongTaskEventSess public final class com/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; + public static final field CPP Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; @@ -3349,7 +3517,6 @@ public final class com/datadog/android/rum/model/LongTaskEvent$LongTaskEventSour public static final field MAUI Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final field ROKU Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final field UNITY Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$LongTaskEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -3537,6 +3704,26 @@ public final class com/datadog/android/rum/model/LongTaskEvent$SessionPreconditi public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$SessionPrecondition; } +public final class com/datadog/android/rum/model/LongTaskEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/LongTaskEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Stream; +} + public final class com/datadog/android/rum/model/LongTaskEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -3564,6 +3751,26 @@ public final class com/datadog/android/rum/model/LongTaskEvent$Synthetics$Compan public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Synthetics; } +public final class com/datadog/android/rum/model/LongTaskEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/LongTaskEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/LongTaskEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/LongTaskEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/LongTaskEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/LongTaskEvent$Tab; +} + public final class com/datadog/android/rum/model/LongTaskEvent$Usr { public static final field Companion Lcom/datadog/android/rum/model/LongTaskEvent$Usr$Companion; public fun ()V @@ -3618,24 +3825,26 @@ public final class com/datadog/android/rum/model/LongTaskEvent$Viewport$Companio public final class com/datadog/android/rum/model/ResourceEvent { public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Companion; - public fun (JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;)V - public synthetic fun (JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Tab;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Stream;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;)V + public synthetic fun (JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Tab;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Stream;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView; public final fun component11 ()Lcom/datadog/android/rum/model/ResourceEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/ResourceEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/ResourceEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/ResourceEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/ResourceEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/ResourceEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/ResourceEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/ResourceEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/ResourceEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/ResourceEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/ResourceEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/ResourceEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/ResourceEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/ResourceEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/ResourceEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/ResourceEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/ResourceEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/ResourceEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/ResourceEvent$Action; - public final fun component22 ()Lcom/datadog/android/rum/model/ResourceEvent$Container; - public final fun component23 ()Lcom/datadog/android/rum/model/ResourceEvent$Resource; + public final fun component20 ()Lcom/datadog/android/rum/model/ResourceEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/ResourceEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/ResourceEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/ResourceEvent$Action; + public final fun component24 ()Lcom/datadog/android/rum/model/ResourceEvent$Container; + public final fun component25 ()Lcom/datadog/android/rum/model/ResourceEvent$Resource; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -3643,8 +3852,8 @@ public final class com/datadog/android/rum/model/ResourceEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; - public final fun copy (JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;)Lcom/datadog/android/rum/model/ResourceEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent;JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent; + public final fun copy (JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Tab;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Stream;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;)Lcom/datadog/android/rum/model/ResourceEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent;JLcom/datadog/android/rum/model/ResourceEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventView;Lcom/datadog/android/rum/model/ResourceEvent$Usr;Lcom/datadog/android/rum/model/ResourceEvent$Account;Lcom/datadog/android/rum/model/ResourceEvent$Tab;Lcom/datadog/android/rum/model/ResourceEvent$Connectivity;Lcom/datadog/android/rum/model/ResourceEvent$Display;Lcom/datadog/android/rum/model/ResourceEvent$Synthetics;Lcom/datadog/android/rum/model/ResourceEvent$CiTest;Lcom/datadog/android/rum/model/ResourceEvent$Os;Lcom/datadog/android/rum/model/ResourceEvent$Device;Lcom/datadog/android/rum/model/ResourceEvent$Dd;Lcom/datadog/android/rum/model/ResourceEvent$Context;Lcom/datadog/android/rum/model/ResourceEvent$Stream;Lcom/datadog/android/rum/model/ResourceEvent$Action;Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$Resource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent; @@ -3667,7 +3876,9 @@ public final class com/datadog/android/rum/model/ResourceEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/ResourceEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/ResourceEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/ResourceEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/ResourceEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -3796,18 +4007,20 @@ public final class com/datadog/android/rum/model/ResourceEvent$Companion { public final class com/datadog/android/rum/model/ResourceEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/ResourceEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/ResourceEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getTraceSampleRate ()Ljava/lang/Number; @@ -3872,15 +4085,15 @@ public final class com/datadog/android/rum/model/ResourceEvent$Connectivity$Comp public final class com/datadog/android/rum/model/ResourceEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/ResourceEvent$ContainerView;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;)V + public fun (Lcom/datadog/android/rum/model/ResourceEvent$ContainerView;Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/ResourceEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; - public final fun copy (Lcom/datadog/android/rum/model/ResourceEvent$ContainerView;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;)Lcom/datadog/android/rum/model/ResourceEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$ContainerView;Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/ResourceEvent$ContainerView;Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource;)Lcom/datadog/android/rum/model/ResourceEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent$Container;Lcom/datadog/android/rum/model/ResourceEvent$ContainerView;Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/ResourceEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -3892,6 +4105,29 @@ public final class com/datadog/android/rum/model/ResourceEvent$Container$Compani public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Container; } +public final class com/datadog/android/rum/model/ResourceEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/ResourceEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/ResourceEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -4663,6 +4899,7 @@ public final class com/datadog/android/rum/model/ResourceEvent$ResourceEventSess public final class com/datadog/android/rum/model/ResourceEvent$ResourceEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; + public static final field CPP Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; @@ -4671,7 +4908,6 @@ public final class com/datadog/android/rum/model/ResourceEvent$ResourceEventSour public static final field MAUI Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final field ROKU Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final field UNITY Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$ResourceEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -4814,6 +5050,26 @@ public final class com/datadog/android/rum/model/ResourceEvent$Status$Companion public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Status; } +public final class com/datadog/android/rum/model/ResourceEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ResourceEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Stream; +} + public final class com/datadog/android/rum/model/ResourceEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -4841,6 +5097,26 @@ public final class com/datadog/android/rum/model/ResourceEvent$Synthetics$Compan public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Synthetics; } +public final class com/datadog/android/rum/model/ResourceEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ResourceEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ResourceEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ResourceEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ResourceEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ResourceEvent$Tab; +} + public final class com/datadog/android/rum/model/ResourceEvent$Usr { public static final field Companion Lcom/datadog/android/rum/model/ResourceEvent$Usr$Companion; public fun ()V @@ -4917,44 +5193,102 @@ public final class com/datadog/android/rum/model/ResourceEvent$Worker$Companion public final class com/datadog/android/rum/model/TimeseriesCpuEvent { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Companion; - public fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;)V - public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; + public fun (JLcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;)V + public synthetic fun (JLcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()J + public final fun component10 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public final fun component11 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; + public final fun component12 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; + public final fun component13 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; - public final fun component3 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; - public final fun component4 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public final fun component5 ()J + public final fun component20 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/lang/String; public final fun component6 ()Ljava/lang/String; public final fun component7 ()Ljava/lang/String; - public final fun component8 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries; - public final fun copy (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; + public final fun component8 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; + public final fun component9 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public final fun copy (JLcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent;JLcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; + public final fun getAccount ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; public final fun getApplication ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; + public final fun getBuildId ()Ljava/lang/String; + public final fun getBuildVersion ()Ljava/lang/String; + public final fun getCiTest ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public final fun getConnectivity ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public final fun getContext ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; public final fun getDate ()J public final fun getDd ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; + public final fun getDdtags ()Ljava/lang/String; + public final fun getDevice ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; + public final fun getDisplay ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public final fun getOs ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; public final fun getService ()Ljava/lang/String; - public final fun getSession ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; + public final fun getSession ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public final fun getStream ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public final fun getSynthetics ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; public final fun getTimeseries ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries; public final fun getType ()Ljava/lang/String; + public final fun getUsr ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; public final fun getVersion ()Ljava/lang/String; + public final fun getView ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Account { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; + public final fun getAdditionalProperties ()Ljava/util/Map; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; public fun toString ()Ljava/lang/String; } +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Account$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Account; +} + public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Application { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application$Companion; - public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; + public final fun getCurrentLocale ()Ljava/lang/String; public final fun getId ()Ljava/lang/String; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -4966,11 +5300,133 @@ public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Application$ public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Application; } +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Cellular { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular$Companion; + public fun ()V + public fun (Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public final fun getCarrierName ()Ljava/lang/String; + public final fun getTechnology ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Cellular$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$CiTest { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public final fun getTestExecutionId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$CiTest$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$CiTest; +} + public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Companion { public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent; } +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Configuration { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration$Companion; + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/Number; + public final fun component2 ()Ljava/lang/Number; + public final fun component3 ()Ljava/lang/Number; + public final fun component4 ()Ljava/lang/Number; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; + public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; + public final fun getSessionReplaySampleRate ()Ljava/lang/Number; + public final fun getSessionSampleRate ()Ljava/lang/Number; + public final fun getTraceSampleRate ()Ljava/lang/Number; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Configuration$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity$Companion; + public fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public final fun component2 ()Ljava/util/List; + public final fun component3 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public final fun component4 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public final fun getCellular ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Cellular; + public final fun getEffectiveType ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public final fun getInterfaces ()Ljava/util/List; + public final fun getStatus ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Connectivity; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Context { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context$Companion; + public fun ()V + public fun (Ljava/util/Map;)V + public synthetic fun (Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/util/Map; + public final fun copy (Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; + public final fun getAdditionalProperties ()Ljava/util/Map; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Context$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Context; +} + public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Data { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Data$Companion; public fun (Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Values;)V @@ -4996,10 +5452,25 @@ public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Data$Compani public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Dd { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd$Companion; public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; + public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; + public final fun getBrowserSdkVersion ()Ljava/lang/String; + public final fun getConfiguration ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Configuration; public final fun getFormatVersion ()J + public final fun getSdkName ()Ljava/lang/String; + public final fun getSession ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; + public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; } public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Dd$Companion { @@ -5007,57 +5478,328 @@ public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Dd$Companion public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Dd; } -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Session { - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session$Companion; - public fun (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type;)V - public final fun component1 ()Ljava/lang/String; - public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; - public final fun copy (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$DdSession { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; public fun equals (Ljava/lang/Object;)Z - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; - public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; - public final fun getId ()Ljava/lang/String; - public final fun getType ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; + public final fun getPlan ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; + public final fun getSessionPrecondition ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; public fun toString ()Ljava/lang/String; } -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Session$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Session; -} - -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Source : java/lang/Enum { - public static final field ANDROID Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field BROWSER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source$Companion; - public static final field ELECTRON Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field FLUTTER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field IOS Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field REACT_NATIVE Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field ROKU Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field RUM_CPP Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final field UNITY Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public final fun toJson ()Lcom/google/gson/JsonElement; - public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; - public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; -} - -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Source$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$DdSession$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DdSession; } -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries { - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries$Companion; - public fun (Ljava/lang/String;JJLcom/datadog/android/rum/model/TimeseriesCpuEvent$Data;)V - public final fun component1 ()Ljava/lang/String; - public final fun component2 ()J - public final fun component3 ()J - public final fun component4 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Data; +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Device { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public final fun component10 ()Ljava/lang/Boolean; + public final fun component11 ()Ljava/lang/Number; + public final fun component12 ()Ljava/lang/Number; + public final fun component13 ()Ljava/lang/Number; + public final fun component14 ()Ljava/lang/Boolean; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/lang/String; + public final fun component6 ()Ljava/lang/String; + public final fun component7 ()Ljava/util/List; + public final fun component8 ()Ljava/lang/String; + public final fun component9 ()Ljava/lang/Number; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; + public final fun getArchitecture ()Ljava/lang/String; + public final fun getBatteryLevel ()Ljava/lang/Number; + public final fun getBrand ()Ljava/lang/String; + public final fun getBrightnessLevel ()Ljava/lang/Number; + public final fun getLocale ()Ljava/lang/String; + public final fun getLocales ()Ljava/util/List; + public final fun getLogicalCpuCount ()Ljava/lang/Number; + public final fun getModel ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getPowerSavingMode ()Ljava/lang/Boolean; + public final fun getTimeZone ()Ljava/lang/String; + public final fun getTotalRam ()Ljava/lang/Number; + public final fun getType ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public fun hashCode ()I + public final fun isLowRam ()Ljava/lang/Boolean; + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Device$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Device; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType : java/lang/Enum { + public static final field BOT Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType$Companion; + public static final field DESKTOP Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final field GAMING_CONSOLE Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final field MOBILE Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final field OTHER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final field TABLET Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final field TV Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$DeviceType; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Display { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public final fun getViewport ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Display$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Display; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType : java/lang/Enum { + public static final field 2G Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public static final field 3G Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public static final field 4G Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType$Companion; + public static final field SLOW_2G Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$EffectiveType; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Interface : java/lang/Enum { + public static final field BLUETOOTH Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field CELLULAR Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface$Companion; + public static final field ETHERNET Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field MIXED Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field NONE Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field OTHER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field UNKNOWN Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field WIFI Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final field WIMAX Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Interface$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Interface; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Os { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; + public final fun getBuild ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getVersion ()Ljava/lang/String; + public final fun getVersionMajor ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Os$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Os; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Plan : java/lang/Enum { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan$Companion; + public static final field PLAN_1 Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; + public static final field PLAN_2 Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Plan$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Plan; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition : java/lang/Enum { + public static final field BACKGROUND_LAUNCH Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition$Companion; + public static final field EXPLICIT_STOP Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final field FROM_NON_INTERACTIVE_SESSION Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final field INACTIVITY_TIMEOUT Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final field MAX_DURATION Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final field PREWARM Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final field USER_APP_LAUNCH Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$SessionPrecondition; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Source : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field BROWSER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field CPP Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field FLUTTER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field IOS Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field MAUI Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field ROKU Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final field UNITY Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Source$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Source; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Status : java/lang/Enum { + public static final field CONNECTED Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status$Companion; + public static final field MAYBE Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public static final field NOT_CONNECTED Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Status$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Status; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Stream; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/Boolean; + public final fun component4 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public final fun getAdditionalProperties ()Ljava/util/Map; + public final fun getInjected ()Ljava/lang/Boolean; + public final fun getResultId ()Ljava/lang/String; + public final fun getTestId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Synthetics; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Tab; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries$Companion; + public fun (Ljava/lang/String;JJLcom/datadog/android/rum/model/TimeseriesCpuEvent$Data;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()J + public final fun component3 ()J + public final fun component4 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Data; public final fun copy (Ljava/lang/String;JJLcom/datadog/android/rum/model/TimeseriesCpuEvent$Data;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries; public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries;Ljava/lang/String;JJLcom/datadog/android/rum/model/TimeseriesCpuEvent$Data;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries; public fun equals (Ljava/lang/Object;)Z @@ -5079,19 +5821,74 @@ public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries$C public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Timeseries; } -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Type : java/lang/Enum { - public static final field CI_TEST Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type$Companion; - public static final field SYNTHETICS Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; - public static final field USER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession$Companion; + public fun (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType;Ljava/lang/Boolean;)V + public synthetic fun (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public final fun component3 ()Ljava/lang/Boolean; + public final fun copy (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType;Ljava/lang/Boolean;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; + public final fun getHasReplay ()Ljava/lang/Boolean; + public final fun getId ()Ljava/lang/String; + public final fun getType ()Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSession; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType : java/lang/Enum { + public static final field CI_TEST Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType$Companion; + public static final field SYNTHETICS Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public static final field USER Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$TimeseriesCpuEventSessionType; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Usr { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr$Companion; + public fun ()V + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; + public final fun getAdditionalProperties ()Ljava/util/Map; + public final fun getAnonymousId ()Ljava/lang/String; + public final fun getEmail ()Ljava/lang/String; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; - public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; - public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; + public fun toString ()Ljava/lang/String; } -public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Type$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Type; +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Usr$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Usr; } public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Values { @@ -5114,131 +5911,567 @@ public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Values$Compa public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Values; } +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$View { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getReferrer ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public final fun setName (Ljava/lang/String;)V + public final fun setReferrer (Ljava/lang/String;)V + public final fun setUrl (Ljava/lang/String;)V + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$View$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$View; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Viewport { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport$Companion; + public fun (Ljava/lang/Number;Ljava/lang/Number;)V + public final fun component1 ()Ljava/lang/Number; + public final fun component2 ()Ljava/lang/Number; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public final fun getHeight ()Ljava/lang/Number; + public final fun getWidth ()Ljava/lang/Number; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesCpuEvent$Viewport$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesCpuEvent$Viewport; +} + public final class com/datadog/android/rum/model/TimeseriesMemoryEvent { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Companion; - public fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;)V - public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public fun (JLcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;)V + public synthetic fun (JLcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()J + public final fun component10 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; + public final fun component11 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; + public final fun component12 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; + public final fun component13 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; - public final fun component3 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; - public final fun component4 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; - public final fun component5 ()J + public final fun component20 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/lang/String; public final fun component6 ()Ljava/lang/String; public final fun component7 ()Ljava/lang/String; - public final fun component8 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries; - public final fun copy (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;JLjava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; + public final fun component8 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; + public final fun component9 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; + public final fun copy (JLcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent;JLcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; + public final fun getAccount ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; public final fun getApplication ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; + public final fun getBuildId ()Ljava/lang/String; + public final fun getBuildVersion ()Ljava/lang/String; + public final fun getCiTest ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public final fun getConnectivity ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public final fun getContext ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; public final fun getDate ()J public final fun getDd ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public final fun getDdtags ()Ljava/lang/String; + public final fun getDevice ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; + public final fun getDisplay ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public final fun getOs ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; public final fun getService ()Ljava/lang/String; - public final fun getSession ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; + public final fun getSession ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; + public final fun getStream ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public final fun getSynthetics ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; public final fun getTimeseries ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries; public final fun getType ()Ljava/lang/String; + public final fun getUsr ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; public final fun getVersion ()Ljava/lang/String; + public final fun getView ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; public fun toString ()Ljava/lang/String; } +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Account { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; + public final fun getAdditionalProperties ()Ljava/util/Map; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Account$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Account; +} + public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Application { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application$Companion; - public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; + public final fun getCurrentLocale ()Ljava/lang/String; public final fun getId ()Ljava/lang/String; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; - public fun toString ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Application$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular$Companion; + public fun ()V + public fun (Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public final fun getCarrierName ()Ljava/lang/String; + public final fun getTechnology ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public final fun getTestExecutionId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$CiTest; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration$Companion; + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/Number; + public final fun component2 ()Ljava/lang/Number; + public final fun component3 ()Ljava/lang/Number; + public final fun component4 ()Ljava/lang/Number; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; + public final fun getSessionReplaySampleRate ()Ljava/lang/Number; + public final fun getSessionSampleRate ()Ljava/lang/Number; + public final fun getTraceSampleRate ()Ljava/lang/Number; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity$Companion; + public fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public final fun component2 ()Ljava/util/List; + public final fun component3 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public final fun component4 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public final fun getCellular ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Cellular; + public final fun getEffectiveType ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public final fun getInterfaces ()Ljava/util/List; + public final fun getStatus ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Connectivity; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Context { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context$Companion; + public fun ()V + public fun (Ljava/util/Map;)V + public synthetic fun (Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/util/Map; + public final fun copy (Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; + public final fun getAdditionalProperties ()Ljava/util/Map; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Context$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Context; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Data { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data$Companion; + public fun (Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values;)V + public final fun component1 ()Ljava/util/List; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values; + public final fun copy (Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; + public final fun getTimestamps ()Ljava/util/List; + public final fun getValues ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Data$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Dd { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public final fun getBrowserSdkVersion ()Ljava/lang/String; + public final fun getConfiguration ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Configuration; + public final fun getFormatVersion ()J + public final fun getSdkName ()Ljava/lang/String; + public final fun getSession ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Dd$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public final fun getPlan ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; + public final fun getSessionPrecondition ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DdSession; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Device { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public final fun component10 ()Ljava/lang/Boolean; + public final fun component11 ()Ljava/lang/Number; + public final fun component12 ()Ljava/lang/Number; + public final fun component13 ()Ljava/lang/Number; + public final fun component14 ()Ljava/lang/Boolean; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/lang/String; + public final fun component6 ()Ljava/lang/String; + public final fun component7 ()Ljava/util/List; + public final fun component8 ()Ljava/lang/String; + public final fun component9 ()Ljava/lang/Number; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Boolean;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; + public final fun getArchitecture ()Ljava/lang/String; + public final fun getBatteryLevel ()Ljava/lang/Number; + public final fun getBrand ()Ljava/lang/String; + public final fun getBrightnessLevel ()Ljava/lang/Number; + public final fun getLocale ()Ljava/lang/String; + public final fun getLocales ()Ljava/util/List; + public final fun getLogicalCpuCount ()Ljava/lang/Number; + public final fun getModel ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getPowerSavingMode ()Ljava/lang/Boolean; + public final fun getTimeZone ()Ljava/lang/String; + public final fun getTotalRam ()Ljava/lang/Number; + public final fun getType ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public fun hashCode ()I + public final fun isLowRam ()Ljava/lang/Boolean; + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Device$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Device; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType : java/lang/Enum { + public static final field BOT Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType$Companion; + public static final field DESKTOP Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final field GAMING_CONSOLE Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final field MOBILE Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final field OTHER Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final field TABLET Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final field TV Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$DeviceType; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Display { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display$Companion; + public fun ()V + public fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport;)V + public synthetic fun (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public final fun copy (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public final fun getViewport ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Display$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Display; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType : java/lang/Enum { + public static final field 2G Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public static final field 3G Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public static final field 4G Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType$Companion; + public static final field SLOW_2G Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Application$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Application; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$EffectiveType; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Interface : java/lang/Enum { + public static final field BLUETOOTH Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field CELLULAR Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface$Companion; + public static final field ETHERNET Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field MIXED Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field NONE Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field OTHER Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field UNKNOWN Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field WIFI Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final field WIMAX Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Data { - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data$Companion; - public fun (Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values;)V - public final fun component1 ()Ljava/util/List; - public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values; - public final fun copy (Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data;Ljava/util/List;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Interface$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Interface; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Os { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; public fun equals (Ljava/lang/Object;)Z - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; - public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; - public final fun getTimestamps ()Ljava/util/List; - public final fun getValues ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; + public final fun getBuild ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getVersion ()Ljava/lang/String; + public final fun getVersionMajor ()Ljava/lang/String; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; public fun toString ()Ljava/lang/String; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Data$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Os$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Os; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Dd { - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd$Companion; - public fun ()V - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; - public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; - public final fun getFormatVersion ()J +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Plan : java/lang/Enum { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan$Companion; + public static final field PLAN_1 Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; + public static final field PLAN_2 Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Dd$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Dd; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Plan$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Plan; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Session { - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session$Companion; - public fun (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type;)V - public final fun component1 ()Ljava/lang/String; - public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; - public final fun copy (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; - public fun equals (Ljava/lang/Object;)Z - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; - public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; - public final fun getId ()Ljava/lang/String; - public final fun getType ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; - public fun hashCode ()I +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition : java/lang/Enum { + public static final field BACKGROUND_LAUNCH Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition$Companion; + public static final field EXPLICIT_STOP Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final field FROM_NON_INTERACTIVE_SESSION Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final field INACTIVITY_TIMEOUT Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final field MAX_DURATION Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final field PREWARM Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final field USER_APP_LAUNCH Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; public final fun toJson ()Lcom/google/gson/JsonElement; - public fun toString ()Ljava/lang/String; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Session$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; - public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Session; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$SessionPrecondition; } public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Source : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field BROWSER Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; + public static final field CPP Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field FLUTTER Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field IOS Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; + public static final field MAUI Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field ROKU Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; - public static final field RUM_CPP Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final field UNITY Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -5250,6 +6483,88 @@ public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Source$Co public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Source; } +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Status : java/lang/Enum { + public static final field CONNECTED Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status$Companion; + public static final field MAYBE Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public static final field NOT_CONNECTED Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Status$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Status; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Stream; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/Boolean; + public final fun component4 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public final fun getAdditionalProperties ()Ljava/util/Map; + public final fun getInjected ()Ljava/lang/Boolean; + public final fun getResultId ()Ljava/lang/String; + public final fun getTestId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Synthetics; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Tab; +} + public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries { public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries$Companion; public fun (Ljava/lang/String;JJLcom/datadog/android/rum/model/TimeseriesMemoryEvent$Data;)V @@ -5278,19 +6593,74 @@ public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Timeserie public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Timeseries; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Type : java/lang/Enum { - public static final field CI_TEST Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; - public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type$Companion; - public static final field SYNTHETICS Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; - public static final field USER Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; - public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession$Companion; + public fun (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType;Ljava/lang/Boolean;)V + public synthetic fun (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public final fun component3 ()Ljava/lang/Boolean; + public final fun copy (Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType;Ljava/lang/Boolean;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession;Ljava/lang/String;Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; + public final fun getHasReplay ()Ljava/lang/Boolean; + public final fun getId ()Ljava/lang/String; + public final fun getType ()Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSession; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType : java/lang/Enum { + public static final field CI_TEST Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType$Companion; + public static final field SYNTHETICS Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public static final field USER Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; + public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$TimeseriesMemoryEventSessionType; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Usr { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr$Companion; + public fun ()V + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun component5 ()Ljava/util/Map; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; + public final fun getAdditionalProperties ()Ljava/util/Map; + public final fun getAnonymousId ()Ljava/lang/String; + public final fun getEmail ()Ljava/lang/String; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; - public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; - public static fun values ()[Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; + public fun toString ()Ljava/lang/String; } -public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Type$Companion { - public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Type; +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Usr$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Usr; } public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Values { @@ -5315,26 +6685,80 @@ public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Values$Co public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Values; } +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$View { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun component4 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; + public final fun getId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getReferrer ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public final fun setName (Ljava/lang/String;)V + public final fun setReferrer (Ljava/lang/String;)V + public final fun setUrl (Ljava/lang/String;)V + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$View$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$View; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport { + public static final field Companion Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport$Companion; + public fun (Ljava/lang/Number;Ljava/lang/Number;)V + public final fun component1 ()Ljava/lang/Number; + public final fun component2 ()Ljava/lang/Number; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public final fun getHeight ()Ljava/lang/Number; + public final fun getWidth ()Ljava/lang/Number; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/TimeseriesMemoryEvent$Viewport; +} + public final class com/datadog/android/rum/model/ViewEvent { public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Companion; - public fun (JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;)V - public synthetic fun (JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Tab;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Stream;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;)V + public synthetic fun (JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Tab;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Stream;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventView; public final fun component11 ()Lcom/datadog/android/rum/model/ViewEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/ViewEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/ViewEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/ViewEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/ViewEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/ViewEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/ViewEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/ViewEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/ViewEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/ViewEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/ViewEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/ViewEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/ViewEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/ViewEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/ViewEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/ViewEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/ViewEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/ViewEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/ViewEvent$Container; - public final fun component22 ()Lcom/datadog/android/rum/model/ViewEvent$Context; - public final fun component23 ()Lcom/datadog/android/rum/model/ViewEvent$Privacy; + public final fun component20 ()Lcom/datadog/android/rum/model/ViewEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/ViewEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/ViewEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/ViewEvent$Container; + public final fun component24 ()Lcom/datadog/android/rum/model/ViewEvent$Context; + public final fun component25 ()Lcom/datadog/android/rum/model/ViewEvent$Privacy; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -5342,8 +6766,8 @@ public final class com/datadog/android/rum/model/ViewEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; - public final fun copy (JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;)Lcom/datadog/android/rum/model/ViewEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent;JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent; + public final fun copy (JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Tab;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Stream;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;)Lcom/datadog/android/rum/model/ViewEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent;JLcom/datadog/android/rum/model/ViewEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;Lcom/datadog/android/rum/model/ViewEvent$ViewEventView;Lcom/datadog/android/rum/model/ViewEvent$Usr;Lcom/datadog/android/rum/model/ViewEvent$Account;Lcom/datadog/android/rum/model/ViewEvent$Tab;Lcom/datadog/android/rum/model/ViewEvent$Connectivity;Lcom/datadog/android/rum/model/ViewEvent$Display;Lcom/datadog/android/rum/model/ViewEvent$Synthetics;Lcom/datadog/android/rum/model/ViewEvent$CiTest;Lcom/datadog/android/rum/model/ViewEvent$Os;Lcom/datadog/android/rum/model/ViewEvent$Device;Lcom/datadog/android/rum/model/ViewEvent$Dd;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Stream;Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$Context;Lcom/datadog/android/rum/model/ViewEvent$Privacy;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent; @@ -5366,7 +6790,9 @@ public final class com/datadog/android/rum/model/ViewEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/ViewEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/ViewEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/ViewEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/ViewEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -5559,19 +6985,21 @@ public final class com/datadog/android/rum/model/ViewEvent$Companion { public final class com/datadog/android/rum/model/ViewEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;Ljava/lang/Boolean;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun component5 ()Ljava/lang/Boolean; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;)Lcom/datadog/android/rum/model/ViewEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun component6 ()Ljava/lang/Boolean; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;Ljava/lang/Boolean;)Lcom/datadog/android/rum/model/ViewEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getStartSessionReplayRecordingManually ()Ljava/lang/Boolean; @@ -5630,15 +7058,15 @@ public final class com/datadog/android/rum/model/ViewEvent$ConnectivityStatus$Co public final class com/datadog/android/rum/model/ViewEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/ViewEvent$ContainerView;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;)V + public fun (Lcom/datadog/android/rum/model/ViewEvent$ContainerView;Lcom/datadog/android/rum/model/ViewEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/ViewEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; - public final fun copy (Lcom/datadog/android/rum/model/ViewEvent$ContainerView;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;)Lcom/datadog/android/rum/model/ViewEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$ContainerView;Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/ViewEvent$ContainerView;Lcom/datadog/android/rum/model/ViewEvent$ContainerSource;)Lcom/datadog/android/rum/model/ViewEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent$Container;Lcom/datadog/android/rum/model/ViewEvent$ContainerView;Lcom/datadog/android/rum/model/ViewEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/ViewEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -5650,6 +7078,29 @@ public final class com/datadog/android/rum/model/ViewEvent$Container$Companion { public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Container; } +public final class com/datadog/android/rum/model/ViewEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/ViewEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/ViewEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -6638,6 +8089,26 @@ public final class com/datadog/android/rum/model/ViewEvent$State$Companion { public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$State; } +public final class com/datadog/android/rum/model/ViewEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ViewEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Stream; +} + public final class com/datadog/android/rum/model/ViewEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -6665,6 +8136,26 @@ public final class com/datadog/android/rum/model/ViewEvent$Synthetics$Companion public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Synthetics; } +public final class com/datadog/android/rum/model/ViewEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/ViewEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/ViewEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/ViewEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/ViewEvent$Tab; +} + public final class com/datadog/android/rum/model/ViewEvent$Usr { public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$Usr$Companion; public fun ()V @@ -6742,6 +8233,7 @@ public final class com/datadog/android/rum/model/ViewEvent$ViewEventSessionType$ public final class com/datadog/android/rum/model/ViewEvent$ViewEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; + public static final field CPP Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final field Companion Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; @@ -6750,7 +8242,6 @@ public final class com/datadog/android/rum/model/ViewEvent$ViewEventSource : jav public static final field MAUI Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final field ROKU Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final field UNITY Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/ViewEvent$ViewEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -6910,23 +8401,25 @@ public final class com/datadog/android/rum/model/ViewEvent$Viewport$Companion { public final class com/datadog/android/rum/model/VitalAppLaunchEvent { public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Companion; - public fun (JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;)V - public synthetic fun (JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;)V + public synthetic fun (JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView; public final fun component11 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; - public final fun component22 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital; + public final fun component20 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; + public final fun component24 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -6934,8 +8427,8 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; - public final fun copy (JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent;JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent; + public final fun copy (JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent;JLcom/datadog/android/rum/model/VitalAppLaunchEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Account;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Connectivity;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Display;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$CiTest;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Os;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Device;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Dd;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Context;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Vital;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent; @@ -6956,7 +8449,9 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -7080,18 +8575,20 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Companion { public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getTraceSampleRate ()Ljava/lang/Number; @@ -7149,15 +8646,15 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Connectivit public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;)V + public fun (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; - public final fun copy (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView;Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -7169,6 +8666,29 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Container$C public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Container; } +public final class com/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -7526,6 +9046,26 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$StartupType public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$StartupType; } +public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Stream; +} + public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -7553,6 +9093,26 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics$ public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Synthetics; } +public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Tab; +} + public final class com/datadog/android/rum/model/VitalAppLaunchEvent$Usr { public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$Usr$Companion; public fun ()V @@ -7684,6 +9244,7 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLau public final class com/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; + public static final field CPP Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final field Companion Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; @@ -7692,7 +9253,6 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLau public static final field MAUI Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final field ROKU Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final field UNITY Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLaunchEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -7736,23 +9296,25 @@ public final class com/datadog/android/rum/model/VitalAppLaunchEvent$VitalAppLau public final class com/datadog/android/rum/model/VitalOperationStepEvent { public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Companion; - public fun (JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;)V - public synthetic fun (JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;)V + public synthetic fun (JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()J public final fun component10 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView; public final fun component11 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr; public final fun component12 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account; - public final fun component13 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity; - public final fun component14 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display; - public final fun component15 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics; - public final fun component16 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest; - public final fun component17 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os; - public final fun component18 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device; - public final fun component19 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd; + public final fun component13 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; + public final fun component14 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity; + public final fun component15 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display; + public final fun component16 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics; + public final fun component17 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest; + public final fun component18 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os; + public final fun component19 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device; public final fun component2 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Application; - public final fun component20 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context; - public final fun component21 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; - public final fun component22 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital; + public final fun component20 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd; + public final fun component21 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context; + public final fun component22 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; + public final fun component23 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; + public final fun component24 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; @@ -7760,8 +9322,8 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent { public final fun component7 ()Ljava/lang/String; public final fun component8 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession; public final fun component9 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; - public final fun copy (JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;)Lcom/datadog/android/rum/model/VitalOperationStepEvent; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent;JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent; + public final fun copy (JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;)Lcom/datadog/android/rum/model/VitalOperationStepEvent; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent;JLcom/datadog/android/rum/model/VitalOperationStepEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Account;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Connectivity;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Display;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics;Lcom/datadog/android/rum/model/VitalOperationStepEvent$CiTest;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Os;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Device;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Dd;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Context;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$Vital;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent; @@ -7782,7 +9344,9 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent { public final fun getService ()Ljava/lang/String; public final fun getSession ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSession; public final fun getSource ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; + public final fun getStream ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; public final fun getSynthetics ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics; + public final fun getTab ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; public final fun getType ()Ljava/lang/String; public final fun getUsr ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr; public final fun getVersion ()Ljava/lang/String; @@ -7892,18 +9456,20 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$Compani public final class com/datadog/android/rum/model/VitalOperationStepEvent$Configuration { public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration$Companion; - public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)V - public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)V + public synthetic fun (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/Number; public final fun component2 ()Ljava/lang/Number; public final fun component3 ()Ljava/lang/Number; public final fun component4 ()Ljava/lang/Number; - public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration; + public final fun component5 ()Ljava/util/List; + public final fun copy (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/Number;Ljava/util/List;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Configuration; public final fun getProfilingSampleRate ()Ljava/lang/Number; + public final fun getSessionReplayExperimentalFeatures ()Ljava/util/List; public final fun getSessionReplaySampleRate ()Ljava/lang/Number; public final fun getSessionSampleRate ()Ljava/lang/Number; public final fun getTraceSampleRate ()Ljava/lang/Number; @@ -7961,15 +9527,15 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$Connect public final class com/datadog/android/rum/model/VitalOperationStepEvent$Container { public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container$Companion; - public fun (Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;)V + public fun (Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource;)V public final fun component1 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView; - public final fun component2 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; - public final fun copy (Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; - public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; + public final fun component2 ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public final fun copy (Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container;Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView;Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; public fun equals (Ljava/lang/Object;)Z public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; - public final fun getSource ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; + public final fun getSource ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; public final fun getView ()Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView; public fun hashCode ()I public final fun toJson ()Lcom/google/gson/JsonElement; @@ -7981,6 +9547,29 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$Contain public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Container; } +public final class com/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource : java/lang/Enum { + public static final field ANDROID Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field BROWSER Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource$Companion; + public static final field ELECTRON Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field FLUTTER Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field IOS Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field KOTLIN_MULTIPLATFORM Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field MAUI Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field REACT_NATIVE Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field ROKU Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field RUM_CPP Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final field UNITY Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public final fun toJson ()Lcom/google/gson/JsonElement; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; + public static fun values ()[Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; +} + +public final class com/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerSource; +} + public final class com/datadog/android/rum/model/VitalOperationStepEvent$ContainerView { public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$ContainerView$Companion; public fun (Ljava/lang/String;)V @@ -8355,6 +9944,26 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$StepTyp public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$StepType; } +public final class com/datadog/android/rum/model/VitalOperationStepEvent$Stream { + public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/VitalOperationStepEvent$Stream$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Stream; +} + public final class com/datadog/android/rum/model/VitalOperationStepEvent$Synthetics { public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics$Companion; public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;)V @@ -8382,6 +9991,26 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$Synthet public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Synthetics; } +public final class com/datadog/android/rum/model/VitalOperationStepEvent$Tab { + public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; + public static synthetic fun copy$default (Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; + public fun equals (Ljava/lang/Object;)Z + public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; + public static final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; + public final fun getId ()Ljava/lang/String; + public fun hashCode ()I + public final fun toJson ()Lcom/google/gson/JsonElement; + public fun toString ()Ljava/lang/String; +} + +public final class com/datadog/android/rum/model/VitalOperationStepEvent$Tab$Companion { + public final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; + public final fun fromJsonObject (Lcom/google/gson/JsonObject;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$Tab; +} + public final class com/datadog/android/rum/model/VitalOperationStepEvent$Usr { public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$Usr$Companion; public fun ()V @@ -8509,6 +10138,7 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$VitalOp public final class com/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource : java/lang/Enum { public static final field ANDROID Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final field BROWSER Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; + public static final field CPP Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final field Companion Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource$Companion; public static final field ELECTRON Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final field FLUTTER Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; @@ -8517,7 +10147,6 @@ public final class com/datadog/android/rum/model/VitalOperationStepEvent$VitalOp public static final field MAUI Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final field REACT_NATIVE Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final field ROKU Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; - public static final field RUM_CPP Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final field UNITY Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public static final fun fromJson (Ljava/lang/String;)Lcom/datadog/android/rum/model/VitalOperationStepEvent$VitalOperationStepEventSource; public final fun toJson ()Lcom/google/gson/JsonElement; @@ -8640,14 +10269,20 @@ public final class com/datadog/android/rum/timeseries/TimeseriesConfiguration { public final class com/datadog/android/rum/timeseries/TimeseriesConfiguration$Builder { public fun ()V public final fun build ()Lcom/datadog/android/rum/timeseries/TimeseriesConfiguration; - public final fun setBufferSize (I)Lcom/datadog/android/rum/timeseries/TimeseriesConfiguration$Builder; - public final fun setIntervalMs (J)Lcom/datadog/android/rum/timeseries/TimeseriesConfiguration$Builder; + public final fun collectOnly ([Lcom/datadog/android/rum/timeseries/TimeseriesType;)Lcom/datadog/android/rum/timeseries/TimeseriesConfiguration$Builder; } public final class com/datadog/android/rum/timeseries/TimeseriesConfiguration$Companion { public final fun getDEFAULT ()Lcom/datadog/android/rum/timeseries/TimeseriesConfiguration; } +public final class com/datadog/android/rum/timeseries/TimeseriesType : java/lang/Enum { + public static final field CPU Lcom/datadog/android/rum/timeseries/TimeseriesType; + public static final field MEMORY Lcom/datadog/android/rum/timeseries/TimeseriesType; + public static fun valueOf (Ljava/lang/String;)Lcom/datadog/android/rum/timeseries/TimeseriesType; + public static fun values ()[Lcom/datadog/android/rum/timeseries/TimeseriesType; +} + public class com/datadog/android/rum/tracking/AcceptAllActivities : com/datadog/android/rum/tracking/ComponentPredicate { public fun ()V public fun accept (Landroid/app/Activity;)Z diff --git a/features/dd-sdk-android-rum/src/main/json/rum/_common-schema.json b/features/dd-sdk-android-rum/src/main/json/rum/_common-schema.json index 991e883116..014d762542 100644 --- a/features/dd-sdk-android-rum/src/main/json/rum/_common-schema.json +++ b/features/dd-sdk-android-rum/src/main/json/rum/_common-schema.json @@ -4,7 +4,7 @@ "title": "CommonProperties", "type": "object", "description": "Schema of common properties of RUM events", - "required": ["date", "application", "session", "view", "_dd"], + "required": ["date", "application", "session", "_dd"], "properties": { "date": { "type": "integer", @@ -92,7 +92,7 @@ "unity", "kotlin-multiplatform", "electron", - "rum-cpp", + "cpp", "maui" ], "readOnly": true @@ -173,6 +173,20 @@ }, "readOnly": true }, + "tab": { + "type": "object", + "description": "Tab properties", + "required": ["id"], + "properties": { + "id": { + "type": "string", + "description": "UUID of the browser tab", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", + "readOnly": true + } + }, + "readOnly": true + }, "connectivity": { "type": "object", "description": "Device connectivity properties", @@ -455,6 +469,14 @@ "minimum": 0, "maximum": 100, "readOnly": true + }, + "session_replay_experimental_features": { + "type": "array", + "description": "Session Replay experimental features enabled in the SDK configuration", + "items": { + "type": "string" + }, + "readOnly": true } } }, @@ -475,6 +497,19 @@ "type": "object", "description": "User provided context", "additionalProperties": true + }, + "stream": { + "type": "object", + "description": "Stream properties", + "required": ["id"], + "properties": { + "id": { + "type": "string", + "description": "UUID of the stream", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", + "readOnly": true + } + } } } } diff --git a/features/dd-sdk-android-rum/src/main/json/rum/timeseries-cpu-schema.json b/features/dd-sdk-android-rum/src/main/json/rum/timeseries-cpu-schema.json index bc7c72f850..9e77f8885c 100644 --- a/features/dd-sdk-android-rum/src/main/json/rum/timeseries-cpu-schema.json +++ b/features/dd-sdk-android-rum/src/main/json/rum/timeseries-cpu-schema.json @@ -4,153 +4,82 @@ "title": "RumTimeseriesCpuEvent", "type": "object", "description": "Schema for a CPU timeseries event.", - "required": ["_dd", "application", "date", "session", "source", "timeseries", "type"], - "properties": { - "type": { - "type": "string", - "description": "RUM event type", - "const": "timeseries", - "readOnly": true + "allOf": [ + { + "$ref": "_common-schema.json" }, - "_dd": { - "type": "object", - "description": "Internal properties", - "required": ["format_version"], + { + "required": ["type", "timeseries"], "properties": { - "format_version": { - "type": "integer", - "const": 2, - "description": "Version of the RUM event format", - "readOnly": true - } - }, - "readOnly": true - }, - "application": { - "type": "object", - "description": "Application properties", - "required": ["id"], - "properties": { - "id": { - "type": "string", - "description": "UUID of the application", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", - "readOnly": true - } - }, - "readOnly": true - }, - "session": { - "type": "object", - "description": "Session properties", - "required": ["id", "type"], - "properties": { - "id": { - "type": "string", - "description": "UUID of the session", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", - "readOnly": true - }, "type": { "type": "string", - "description": "Type of the session", - "enum": ["user", "synthetics", "ci_test"], - "readOnly": true - } - }, - "readOnly": true - }, - "source": { - "type": "string", - "description": "The source of this event", - "enum": [ - "android", - "ios", - "browser", - "flutter", - "react-native", - "roku", - "unity", - "kotlin-multiplatform", - "electron", - "rum-cpp" - ], - "readOnly": true - }, - "date": { - "type": "integer", - "description": "Start of the event in ms from epoch", - "minimum": 0, - "readOnly": true - }, - "service": { - "type": "string", - "description": "The service name for this application" - }, - "version": { - "type": "string", - "description": "The version for this application" - }, - "timeseries": { - "type": "object", - "description": "CPU timeseries properties", - "required": ["id", "name", "schema", "start", "end", "data"], - "properties": { - "id": { - "type": "string", - "description": "UUID of the timeseries batch", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", + "description": "RUM event type", + "const": "timeseries", "readOnly": true }, - "name": { - "type": "string", - "description": "Name identifying the timeseries metric", - "const": "cpu", - "readOnly": true - }, - "schema": { - "type": "string", - "description": "Wire-shape discriminator for the data field", - "const": "object-v2", - "readOnly": true - }, - "start": { - "type": "integer", - "description": "Timestamp of the first sample in nanoseconds from epoch", - "readOnly": true - }, - "end": { - "type": "integer", - "description": "Timestamp of the last sample in nanoseconds from epoch", - "readOnly": true - }, - "data": { + "timeseries": { "type": "object", - "description": "Flattened CPU data points", - "required": ["timestamps", "values"], + "description": "CPU timeseries properties", + "required": ["id", "name", "schema", "start", "end", "data"], "properties": { - "timestamps": { - "type": "array", - "description": "Sample timestamps in nanoseconds from epoch", - "items": { - "type": "integer", - "readOnly": true - }, + "id": { + "type": "string", + "description": "UUID of the timeseries batch", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", "readOnly": true }, - "values": { + "name": { + "type": "string", + "description": "Name identifying the timeseries metric", + "const": "cpu", + "readOnly": true + }, + "schema": { + "type": "string", + "description": "Wire-shape discriminator for the data field", + "const": "object-v2", + "readOnly": true + }, + "start": { + "type": "integer", + "description": "Timestamp of the first sample in nanoseconds from epoch", + "readOnly": true + }, + "end": { + "type": "integer", + "description": "Timestamp of the last sample in nanoseconds from epoch", + "readOnly": true + }, + "data": { "type": "object", - "description": "CPU measurements, aligned index-for-index with timestamps", - "required": ["cpu_usage"], + "description": "Flattened CPU data points", + "required": ["timestamps", "values"], "properties": { - "cpu_usage": { + "timestamps": { "type": "array", - "description": "CPU usage as a percentage (0.0 to 100.0)", + "description": "Sample timestamps in nanoseconds from epoch", "items": { - "type": "number", + "type": "integer", "readOnly": true }, "readOnly": true + }, + "values": { + "type": "object", + "description": "CPU measurements, aligned index-for-index with timestamps", + "required": ["cpu_usage"], + "properties": { + "cpu_usage": { + "type": "array", + "description": "CPU usage as a percentage (0.0 to 100.0)", + "items": { + "type": "number", + "readOnly": true + }, + "readOnly": true + } + }, + "readOnly": true } }, "readOnly": true @@ -158,8 +87,7 @@ }, "readOnly": true } - }, - "readOnly": true + } } - } + ] } diff --git a/features/dd-sdk-android-rum/src/main/json/rum/timeseries-memory-schema.json b/features/dd-sdk-android-rum/src/main/json/rum/timeseries-memory-schema.json index 9e642e1a8d..122f58d670 100644 --- a/features/dd-sdk-android-rum/src/main/json/rum/timeseries-memory-schema.json +++ b/features/dd-sdk-android-rum/src/main/json/rum/timeseries-memory-schema.json @@ -4,160 +4,89 @@ "title": "RumTimeseriesMemoryEvent", "type": "object", "description": "Schema for a memory timeseries event.", - "required": ["_dd", "application", "date", "session", "source", "timeseries", "type"], - "properties": { - "type": { - "type": "string", - "description": "RUM event type", - "const": "timeseries", - "readOnly": true + "allOf": [ + { + "$ref": "_common-schema.json" }, - "_dd": { - "type": "object", - "description": "Internal properties", - "required": ["format_version"], + { + "required": ["type", "timeseries"], "properties": { - "format_version": { - "type": "integer", - "const": 2, - "description": "Version of the RUM event format", - "readOnly": true - } - }, - "readOnly": true - }, - "application": { - "type": "object", - "description": "Application properties", - "required": ["id"], - "properties": { - "id": { - "type": "string", - "description": "UUID of the application", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", - "readOnly": true - } - }, - "readOnly": true - }, - "session": { - "type": "object", - "description": "Session properties", - "required": ["id", "type"], - "properties": { - "id": { - "type": "string", - "description": "UUID of the session", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", - "readOnly": true - }, "type": { "type": "string", - "description": "Type of the session", - "enum": ["user", "synthetics", "ci_test"], - "readOnly": true - } - }, - "readOnly": true - }, - "source": { - "type": "string", - "description": "The source of this event", - "enum": [ - "android", - "ios", - "browser", - "flutter", - "react-native", - "roku", - "unity", - "kotlin-multiplatform", - "electron", - "rum-cpp" - ], - "readOnly": true - }, - "date": { - "type": "integer", - "description": "Start of the event in ms from epoch", - "minimum": 0, - "readOnly": true - }, - "service": { - "type": "string", - "description": "The service name for this application" - }, - "version": { - "type": "string", - "description": "The version for this application" - }, - "timeseries": { - "type": "object", - "description": "Memory timeseries properties", - "required": ["id", "name", "schema", "start", "end", "data"], - "properties": { - "id": { - "type": "string", - "description": "UUID of the timeseries batch", - "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", + "description": "RUM event type", + "const": "timeseries", "readOnly": true }, - "name": { - "type": "string", - "description": "Name identifying the timeseries metric", - "const": "memory", - "readOnly": true - }, - "schema": { - "type": "string", - "description": "Wire-shape discriminator for the data field", - "const": "object-v2", - "readOnly": true - }, - "start": { - "type": "integer", - "description": "Timestamp of the first sample in nanoseconds from epoch", - "readOnly": true - }, - "end": { - "type": "integer", - "description": "Timestamp of the last sample in nanoseconds from epoch", - "readOnly": true - }, - "data": { + "timeseries": { "type": "object", - "description": "Flattened memory data points", - "required": ["timestamps", "values"], + "description": "Memory timeseries properties", + "required": ["id", "name", "schema", "start", "end", "data"], "properties": { - "timestamps": { - "type": "array", - "description": "Sample timestamps in nanoseconds from epoch", - "items": { - "type": "integer", - "readOnly": true - }, + "id": { + "type": "string", + "description": "UUID of the timeseries batch", + "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", "readOnly": true }, - "values": { + "name": { + "type": "string", + "description": "Name identifying the timeseries metric", + "const": "memory", + "readOnly": true + }, + "schema": { + "type": "string", + "description": "Wire-shape discriminator for the data field", + "const": "object-v2", + "readOnly": true + }, + "start": { + "type": "integer", + "description": "Timestamp of the first sample in nanoseconds from epoch", + "readOnly": true + }, + "end": { + "type": "integer", + "description": "Timestamp of the last sample in nanoseconds from epoch", + "readOnly": true + }, + "data": { "type": "object", - "description": "Memory measurements, aligned index-for-index with timestamps", - "required": ["memory_footprint", "memory_percent"], + "description": "Flattened memory data points", + "required": ["timestamps", "values"], "properties": { - "memory_footprint": { + "timestamps": { "type": "array", - "description": "Physical memory footprint of the process in kilobytes", + "description": "Sample timestamps in nanoseconds from epoch", "items": { - "type": "number", + "type": "integer", "readOnly": true }, "readOnly": true }, - "memory_percent": { - "type": "array", - "description": "Memory footprint as a percentage of total device RAM", - "items": { - "type": "number", - "readOnly": true + "values": { + "type": "object", + "description": "Memory measurements, aligned index-for-index with timestamps", + "required": ["memory_footprint", "memory_percent"], + "properties": { + "memory_footprint": { + "type": "array", + "description": "Physical memory footprint of the process in kilobytes", + "items": { + "type": "number", + "readOnly": true + }, + "readOnly": true + }, + "memory_percent": { + "type": "array", + "description": "Memory footprint as a percentage of total device RAM", + "items": { + "type": "number", + "readOnly": true + }, + "readOnly": true + } }, "readOnly": true } @@ -167,8 +96,7 @@ }, "readOnly": true } - }, - "readOnly": true + } } - } + ] } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/RumConfiguration.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/RumConfiguration.kt index 0146aa8773..6049fcaff7 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/RumConfiguration.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/RumConfiguration.kt @@ -412,20 +412,16 @@ data class RumConfiguration internal constructor( } /** - * Enables memory and CPU timeseries collection. + * Enables device timeseries collection. * - * When enabled, the SDK samples device memory (RSS) and CPU usage at - * [TimeseriesConfiguration.intervalMs] (default 1 second) and emits a batched - * timeseries event every [TimeseriesConfiguration.bufferSize] samples (default 30). - * Sampling runs on the shared RUM vitals background executor. + * By default, all supported timeseries types are collected. Use + * [TimeseriesConfiguration.Builder.collectOnly] to restrict collection to specific types. * - * To disable, pass null. - * - * @param configuration optional fine-tuning of sampling interval and batch size. + * @param configuration configuration for timeseries collection. */ @ExperimentalRumApi fun setTimeseriesConfiguration( - configuration: TimeseriesConfiguration? + configuration: TimeseriesConfiguration ): Builder { rumConfig = rumConfig.copy(timeseriesConfiguration = configuration) return this diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt index 64e93cfd17..28edfb59b3 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt @@ -91,15 +91,9 @@ import com.datadog.android.rum.internal.startup.RumAppStartupDetector import com.datadog.android.rum.internal.startup.RumStartupScenario import com.datadog.android.rum.internal.startup.RumTTIDInfo import com.datadog.android.rum.internal.thread.NoOpScheduledExecutorService -import com.datadog.android.rum.internal.timeseries.Buffer import com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollectorFactory import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory -import com.datadog.android.rum.internal.timeseries.Pipeline import com.datadog.android.rum.internal.timeseries.TimeseriesCollector -import com.datadog.android.rum.internal.timeseries.provider.CpuDatapointReader -import com.datadog.android.rum.internal.timeseries.provider.VitalReaderWrapper -import com.datadog.android.rum.internal.timeseries.serializer.CpuEventSerializer -import com.datadog.android.rum.internal.timeseries.serializer.MemoryEventSerializer import com.datadog.android.rum.internal.tracking.JetpackViewAttributesProvider import com.datadog.android.rum.internal.tracking.NoOpInteractionPredicate import com.datadog.android.rum.internal.tracking.NoOpUserActionTrackingStrategy @@ -302,11 +296,16 @@ internal class RumFeature( sessionListener = configuration.sessionListener - configuration.timeseriesConfiguration?.let { configuration -> - timeseriesCollectorFactory = createTimeseriesCollectingFactory( - configuration, - appContext.readTotalRamBytes(sdkCore.internalLogger) ?: 0L, - insightsCollector + configuration.timeseriesConfiguration?.let { timeseriesConfiguration -> + timeseriesCollectorFactory = DefaultTimeseriesCollectorFactory( + sdkCore = sdkCore, + dataWriter = dataWriter, + insightsCollector = insightsCollector, + configuration = timeseriesConfiguration, + scheduledExecutorService = vitalExecutorService, + totalRamBytes = appContext.readTotalRamBytes(sdkCore.internalLogger) ?: 0L, + batteryInfoProvider = batteryInfoProvider, + displayInfoProvider = displayInfoProvider ) } @@ -452,67 +451,6 @@ internal class RumFeature( ) } - @Suppress("LongMethod") - internal fun createTimeseriesCollectingFactory( - configuration: TimeseriesConfiguration, - totalRamBytes: Long, - insightsCollector: InsightsCollector - ): TimeseriesCollector.Factory = DefaultTimeseriesCollectorFactory( - internalLogger = sdkCore.internalLogger, - scheduledExecutorService = vitalExecutorService, - pipelinesProvider = { applicationId, sessionId, sessionType -> - listOfNotNull( - Pipeline( - sdkCore = sdkCore, - reader = CpuDatapointReader( - cpuStatReader = CpuStatReader(internalLogger = sdkCore.internalLogger), - cpuTimeProvider = sdkCore.timeProvider, - intervalMs = configuration.intervalMs - ), - buffer = Buffer(configuration.bufferSize), - serializer = CpuEventSerializer( - sessionId = sessionId, - applicationId = applicationId, - sessionType = sessionType, - timeProvider = sdkCore.timeProvider - ), - dataWriter = dataWriter, - internalLogger = sdkCore.internalLogger, - insightsCollector = insightsCollector - ), - if (totalRamBytes > 0L) { - Pipeline( - sdkCore = sdkCore, - reader = VitalReaderWrapper( - vitalReader = MemoryVitalReader(internalLogger = sdkCore.internalLogger), - timeProvider = sdkCore.timeProvider, - intervalMs = configuration.intervalMs - ), - buffer = Buffer(configuration.bufferSize), - serializer = MemoryEventSerializer( - sessionId = sessionId, - applicationId = applicationId, - sessionType = sessionType, - totalRamBytes = totalRamBytes, - timeProvider = sdkCore.timeProvider - ), - dataWriter = dataWriter, - internalLogger = sdkCore.internalLogger, - insightsCollector = insightsCollector - ) - } else { - sdkCore.internalLogger.log( - InternalLogger.Level.WARN, - InternalLogger.Target.USER, - { MEMORY_TIMESERIES_DISABLED_MESSAGE }, - onlyOnce = true - ) - null - } - ) - } - ) - // region FeatureEventReceiver override fun onReceive(event: Any) { @@ -974,8 +912,6 @@ internal class RumFeature( "Slow frames monitoring enabled." internal const val SLOW_FRAMES_MONITORING_DISABLED_MESSAGE = "Slow frames monitoring disabled." - internal const val MEMORY_TIMESERIES_DISABLED_MESSAGE = - "Unable to read total device memory; memory timeseries collection is disabled." internal const val RUM_FEATURE_NOT_YET_INITIALIZED = "RUM feature is not initialized yet, you need to register it with a" + " SDK instance by calling SdkCore#registerFeature method." diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumSessionTypeExt.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumSessionTypeExt.kt index 49105fdc95..ff9ee46572 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumSessionTypeExt.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumSessionTypeExt.kt @@ -11,8 +11,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent -import com.datadog.android.rum.model.TimeseriesCpuEvent -import com.datadog.android.rum.model.TimeseriesMemoryEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent.TimeseriesCpuEventSessionType +import com.datadog.android.rum.model.TimeseriesMemoryEvent.TimeseriesMemoryEventSessionType import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -66,12 +66,12 @@ internal fun RumSessionType.toVitalAppLaunch(): VitalAppLaunchEvent.VitalAppLaun } } -internal fun RumSessionType.toTimeseriesMemorySessionType(): TimeseriesMemoryEvent.Type = when (this) { - RumSessionType.SYNTHETICS -> TimeseriesMemoryEvent.Type.SYNTHETICS - RumSessionType.USER -> TimeseriesMemoryEvent.Type.USER +internal fun RumSessionType.toTimeseriesMemorySessionType(): TimeseriesMemoryEventSessionType = when (this) { + RumSessionType.SYNTHETICS -> TimeseriesMemoryEventSessionType.SYNTHETICS + RumSessionType.USER -> TimeseriesMemoryEventSessionType.USER } -internal fun RumSessionType.toTimeseriesCpuSessionType(): TimeseriesCpuEvent.Type = when (this) { - RumSessionType.SYNTHETICS -> TimeseriesCpuEvent.Type.SYNTHETICS - RumSessionType.USER -> TimeseriesCpuEvent.Type.USER +internal fun RumSessionType.toTimeseriesCpuSessionType(): TimeseriesCpuEventSessionType = when (this) { + RumSessionType.SYNTHETICS -> TimeseriesCpuEventSessionType.SYNTHETICS + RumSessionType.USER -> TimeseriesCpuEventSessionType.USER } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/RumDataWriter.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/RumDataWriter.kt index 24c4f018c8..3c8ce66086 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/RumDataWriter.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/RumDataWriter.kt @@ -22,6 +22,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -106,6 +108,8 @@ internal class RumDataWriter( is TelemetryDebugEvent -> event.type is TelemetryErrorEvent -> event.type is TelemetryUsageEvent -> event.type + is TimeseriesCpuEvent -> event.type + is TimeseriesMemoryEvent -> event.type else -> UNKNOWN_EVENT_TYPE } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt index e932bea14a..c11ccfcb3d 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapper.kt @@ -13,6 +13,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -67,6 +69,8 @@ internal data class RumEventMapper( is VitalOperationStepEvent -> vitalOperationStepEventMapper.map(event) is VitalAppLaunchEvent -> vitalAppLaunchEventMapper.map(event) is TelemetryConfigurationEvent -> telemetryConfigurationMapper.map(event) + is TimeseriesCpuEvent, + is TimeseriesMemoryEvent, is TelemetryDebugEvent, is TelemetryUsageEvent, is TelemetryErrorEvent -> event diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializer.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializer.kt index ea867f6cc9..96915488be 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializer.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializer.kt @@ -16,6 +16,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -68,6 +70,12 @@ internal class RumEventSerializer( is TelemetryUsageEvent -> { model.toJson().toString() } + is TimeseriesCpuEvent -> { + model.toJson().toString() + } + is TimeseriesMemoryEvent -> { + model.toJson().toString() + } is JsonObject -> { model.toString() } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExt.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExt.kt index d92742407e..9ecc79ae71 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExt.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExt.kt @@ -8,19 +8,26 @@ package com.datadog.android.rum.internal.domain.scope import com.datadog.android.api.InternalLogger +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.api.context.DeviceInfo import com.datadog.android.api.context.DeviceType import com.datadog.android.api.context.NetworkInfo +import com.datadog.android.api.feature.Feature import com.datadog.android.rum.RumActionType import com.datadog.android.rum.RumErrorSource import com.datadog.android.rum.RumResourceKind import com.datadog.android.rum.RumResourceMethod import com.datadog.android.rum.internal.RumErrorSourceType +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo import com.datadog.android.rum.internal.domain.event.ResourceTiming import com.datadog.android.rum.internal.startup.RumStartupScenario import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -426,6 +433,80 @@ internal fun NetworkInfo.toAppLaunchVitalConnectivity(): VitalAppLaunchEvent.Con ) } +internal fun NetworkInfo.toTimeseriesCpuConnectivity(): TimeseriesCpuEvent.Connectivity { + val status = if (isConnected()) { + TimeseriesCpuEvent.Status.CONNECTED + } else { + TimeseriesCpuEvent.Status.NOT_CONNECTED + } + val interfaces = when (connectivity) { + NetworkInfo.Connectivity.NETWORK_ETHERNET -> listOf(TimeseriesCpuEvent.Interface.ETHERNET) + NetworkInfo.Connectivity.NETWORK_WIFI -> listOf(TimeseriesCpuEvent.Interface.WIFI) + NetworkInfo.Connectivity.NETWORK_WIMAX -> listOf(TimeseriesCpuEvent.Interface.WIMAX) + NetworkInfo.Connectivity.NETWORK_BLUETOOTH -> listOf(TimeseriesCpuEvent.Interface.BLUETOOTH) + NetworkInfo.Connectivity.NETWORK_2G, + NetworkInfo.Connectivity.NETWORK_3G, + NetworkInfo.Connectivity.NETWORK_4G, + NetworkInfo.Connectivity.NETWORK_5G, + NetworkInfo.Connectivity.NETWORK_MOBILE_OTHER, + NetworkInfo.Connectivity.NETWORK_CELLULAR -> listOf(TimeseriesCpuEvent.Interface.CELLULAR) + + NetworkInfo.Connectivity.NETWORK_OTHER -> listOf(TimeseriesCpuEvent.Interface.OTHER) + NetworkInfo.Connectivity.NETWORK_NOT_CONNECTED -> emptyList() + } + + val cellular = if (cellularTechnology != null || carrierName != null) { + TimeseriesCpuEvent.Cellular( + technology = cellularTechnology, + carrierName = carrierName + ) + } else { + null + } + return TimeseriesCpuEvent.Connectivity( + status, + interfaces, + cellular = cellular + ) +} + +internal fun NetworkInfo.toTimeseriesMemoryConnectivity(): TimeseriesMemoryEvent.Connectivity { + val status = if (isConnected()) { + TimeseriesMemoryEvent.Status.CONNECTED + } else { + TimeseriesMemoryEvent.Status.NOT_CONNECTED + } + val interfaces = when (connectivity) { + NetworkInfo.Connectivity.NETWORK_ETHERNET -> listOf(TimeseriesMemoryEvent.Interface.ETHERNET) + NetworkInfo.Connectivity.NETWORK_WIFI -> listOf(TimeseriesMemoryEvent.Interface.WIFI) + NetworkInfo.Connectivity.NETWORK_WIMAX -> listOf(TimeseriesMemoryEvent.Interface.WIMAX) + NetworkInfo.Connectivity.NETWORK_BLUETOOTH -> listOf(TimeseriesMemoryEvent.Interface.BLUETOOTH) + NetworkInfo.Connectivity.NETWORK_2G, + NetworkInfo.Connectivity.NETWORK_3G, + NetworkInfo.Connectivity.NETWORK_4G, + NetworkInfo.Connectivity.NETWORK_5G, + NetworkInfo.Connectivity.NETWORK_MOBILE_OTHER, + NetworkInfo.Connectivity.NETWORK_CELLULAR -> listOf(TimeseriesMemoryEvent.Interface.CELLULAR) + + NetworkInfo.Connectivity.NETWORK_OTHER -> listOf(TimeseriesMemoryEvent.Interface.OTHER) + NetworkInfo.Connectivity.NETWORK_NOT_CONNECTED -> emptyList() + } + + val cellular = if (cellularTechnology != null || carrierName != null) { + TimeseriesMemoryEvent.Cellular( + technology = cellularTechnology, + carrierName = carrierName + ) + } else { + null + } + return TimeseriesMemoryEvent.Connectivity( + status, + interfaces, + cellular = cellular + ) +} + internal fun NetworkInfo.isConnected(): Boolean { return connectivity != NetworkInfo.Connectivity.NETWORK_NOT_CONNECTED } @@ -518,6 +599,94 @@ internal fun DeviceType.toVitalAppLaunchSchemaType(): VitalAppLaunchEvent.Device } } +internal fun DeviceType.toTimeseriesCpuSchemaType(): TimeseriesCpuEvent.DeviceType { + return when (this) { + DeviceType.MOBILE -> TimeseriesCpuEvent.DeviceType.MOBILE + DeviceType.TABLET -> TimeseriesCpuEvent.DeviceType.TABLET + DeviceType.TV -> TimeseriesCpuEvent.DeviceType.TV + DeviceType.DESKTOP -> TimeseriesCpuEvent.DeviceType.DESKTOP + DeviceType.GAMING_CONSOLE -> TimeseriesCpuEvent.DeviceType.GAMING_CONSOLE + DeviceType.BOT -> TimeseriesCpuEvent.DeviceType.BOT + DeviceType.OTHER -> TimeseriesCpuEvent.DeviceType.OTHER + } +} + +internal fun DeviceType.toTimeseriesMemorySchemaType(): TimeseriesMemoryEvent.DeviceType { + return when (this) { + DeviceType.MOBILE -> TimeseriesMemoryEvent.DeviceType.MOBILE + DeviceType.TABLET -> TimeseriesMemoryEvent.DeviceType.TABLET + DeviceType.TV -> TimeseriesMemoryEvent.DeviceType.TV + DeviceType.DESKTOP -> TimeseriesMemoryEvent.DeviceType.DESKTOP + DeviceType.GAMING_CONSOLE -> TimeseriesMemoryEvent.DeviceType.GAMING_CONSOLE + DeviceType.BOT -> TimeseriesMemoryEvent.DeviceType.BOT + DeviceType.OTHER -> TimeseriesMemoryEvent.DeviceType.OTHER + } +} + +internal fun DeviceInfo.toTimeseriesCpuDevice( + batteryInfo: BatteryInfo, + displayInfo: DisplayInfo +) = TimeseriesCpuEvent.Device( + type = deviceType.toTimeseriesCpuSchemaType(), + name = deviceName, + model = deviceModel, + brand = deviceBrand, + architecture = architecture, + locales = localeInfo.locales, + timeZone = localeInfo.timeZone, + batteryLevel = batteryInfo.batteryLevel, + powerSavingMode = batteryInfo.lowPowerMode, + brightnessLevel = displayInfo.screenBrightness, + logicalCpuCount = logicalCpuCount, + totalRam = totalRam, + isLowRam = isLowRam +) + +internal fun DeviceInfo.toTimeseriesMemoryDevice( + batteryInfo: BatteryInfo, + displayInfo: DisplayInfo +) = TimeseriesMemoryEvent.Device( + type = deviceType.toTimeseriesMemorySchemaType(), + name = deviceName, + model = deviceModel, + brand = deviceBrand, + architecture = architecture, + locales = localeInfo.locales, + timeZone = localeInfo.timeZone, + batteryLevel = batteryInfo.batteryLevel, + powerSavingMode = batteryInfo.lowPowerMode, + brightnessLevel = displayInfo.screenBrightness, + logicalCpuCount = logicalCpuCount, + totalRam = totalRam, + isLowRam = isLowRam +) + +internal fun DeviceInfo.toTimeseriesCpuOs() = TimeseriesCpuEvent.Os( + name = osName, + version = osVersion, + versionMajor = osMajorVersion +) + +internal fun DeviceInfo.toTimeseriesMemoryOs() = TimeseriesMemoryEvent.Os( + name = osName, + version = osVersion, + versionMajor = osMajorVersion +) + +// endregion + +// region Feature context sample rates + +internal fun DatadogContext.resolveSessionReplaySampleRate(): Long? { + val srContext = featuresContext[Feature.SESSION_REPLAY_FEATURE_NAME] + return srContext?.get(RumViewScope.SESSION_REPLAY_SAMPLE_RATE_KEY) as? Long +} + +internal fun DatadogContext.resolveTraceSampleRate(): Float? { + val tracingContext = featuresContext[Feature.TRACING_FEATURE_NAME] + return tracingContext?.get(RumViewScope.TRACE_SAMPLE_RATE) as? Float +} + // endregion // region Source @@ -641,6 +810,40 @@ internal fun VitalAppLaunchEvent.VitalAppLaunchEventSource.Companion.tryFromSour } } +internal fun TimeseriesCpuEvent.Source.Companion.tryFromSource( + source: String, + internalLogger: InternalLogger +): TimeseriesCpuEvent.Source? { + return try { + fromJson(source) + } catch (e: NoSuchElementException) { + internalLogger.log( + InternalLogger.Level.ERROR, + InternalLogger.Target.USER, + { UNKNOWN_SOURCE_WARNING_MESSAGE_FORMAT.format(Locale.US, source) }, + e + ) + null + } +} + +internal fun TimeseriesMemoryEvent.Source.Companion.tryFromSource( + source: String, + internalLogger: InternalLogger +): TimeseriesMemoryEvent.Source? { + return try { + fromJson(source) + } catch (e: NoSuchElementException) { + internalLogger.log( + InternalLogger.Level.ERROR, + InternalLogger.Target.USER, + { UNKNOWN_SOURCE_WARNING_MESSAGE_FORMAT.format(Locale.US, source) }, + e + ) + null + } +} + internal const val UNKNOWN_SOURCE_WARNING_MESSAGE_FORMAT = "You are using an unknown " + "source %s for your events" @@ -713,6 +916,33 @@ internal fun RumSessionScope.StartReason.toLongTaskSessionPrecondition(): LongTa } } +internal fun RumSessionScope.StartReason.toTimeseriesCpuSessionPrecondition(): TimeseriesCpuEvent.SessionPrecondition { + return when (this) { + RumSessionScope.StartReason.USER_APP_LAUNCH -> TimeseriesCpuEvent.SessionPrecondition.USER_APP_LAUNCH + RumSessionScope.StartReason.INACTIVITY_TIMEOUT -> TimeseriesCpuEvent.SessionPrecondition.INACTIVITY_TIMEOUT + RumSessionScope.StartReason.MAX_DURATION -> TimeseriesCpuEvent.SessionPrecondition.MAX_DURATION + RumSessionScope.StartReason.EXPLICIT_STOP -> TimeseriesCpuEvent.SessionPrecondition.EXPLICIT_STOP + RumSessionScope.StartReason.BACKGROUND_LAUNCH -> TimeseriesCpuEvent.SessionPrecondition.BACKGROUND_LAUNCH + RumSessionScope.StartReason.PREWARM -> TimeseriesCpuEvent.SessionPrecondition.PREWARM + RumSessionScope.StartReason.FROM_NON_INTERACTIVE_SESSION -> + TimeseriesCpuEvent.SessionPrecondition.FROM_NON_INTERACTIVE_SESSION + } +} + +internal fun RumSessionScope.StartReason.toTimeseriesMemorySessionPrecondition(): + TimeseriesMemoryEvent.SessionPrecondition { + return when (this) { + RumSessionScope.StartReason.USER_APP_LAUNCH -> TimeseriesMemoryEvent.SessionPrecondition.USER_APP_LAUNCH + RumSessionScope.StartReason.INACTIVITY_TIMEOUT -> TimeseriesMemoryEvent.SessionPrecondition.INACTIVITY_TIMEOUT + RumSessionScope.StartReason.MAX_DURATION -> TimeseriesMemoryEvent.SessionPrecondition.MAX_DURATION + RumSessionScope.StartReason.EXPLICIT_STOP -> TimeseriesMemoryEvent.SessionPrecondition.EXPLICIT_STOP + RumSessionScope.StartReason.BACKGROUND_LAUNCH -> TimeseriesMemoryEvent.SessionPrecondition.BACKGROUND_LAUNCH + RumSessionScope.StartReason.PREWARM -> TimeseriesMemoryEvent.SessionPrecondition.PREWARM + RumSessionScope.StartReason.FROM_NON_INTERACTIVE_SESSION -> + TimeseriesMemoryEvent.SessionPrecondition.FROM_NON_INTERACTIVE_SESSION + } +} + // endregion // region Operation diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt index 0e799a5dc0..a7d42f428a 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt @@ -201,7 +201,11 @@ internal class RumSessionScope( } } - timeseriesCollector.onViewTypeUpdate(getActiveRumContext().viewType) + // getActiveRumContext() copies the whole context chain, so it is only built when there is a + // collector to feed: timeseries collection is opt-in and this runs on every RUM event. + if (timeseriesCollector !is NoOpTimeseriesCollector) { + timeseriesCollector.onRumContextUpdate(getActiveRumContext()) + } return if (isSessionComplete()) { null @@ -234,11 +238,11 @@ internal class RumSessionScope( } private fun startTimeseries() { + val rumContext = getActiveRumContext() timeseriesCollector = timeseriesCollectorFactory.create( - sessionId = sessionId, - applicationId = parentScope.getRumContext().applicationId, - sessionType = getRumContext().resolveSessionType(rumSessionTypeOverride), - viewType = getActiveRumContext().viewType + rumContext = rumContext, + sessionType = rumContext.resolveSessionType(rumSessionTypeOverride), + customAttributes = ::getCustomAttributes ) timeseriesCollector.onSessionStart() } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt index 39540ba7ef..ab07c34939 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt @@ -1448,8 +1448,8 @@ internal open class RumViewScope( replayStats = replayStats, configuration = ViewEvent.Configuration( sessionSampleRate = sampleRate, - sessionReplaySampleRate = resolveSessionReplaySampleRate(datadogContext), - traceSampleRate = resolveTraceSampleRate(datadogContext) + sessionReplaySampleRate = datadogContext.resolveSessionReplaySampleRate(), + traceSampleRate = datadogContext.resolveTraceSampleRate() ), profiling = resolveViewProfilingStatus(datadogContext) ), @@ -1735,16 +1735,6 @@ internal open class RumViewScope( } } - private fun resolveSessionReplaySampleRate(datadogContext: DatadogContext): Long? { - val srContext = datadogContext.featuresContext[Feature.SESSION_REPLAY_FEATURE_NAME] - return srContext?.get(SESSION_REPLAY_SAMPLE_RATE_KEY) as? Long - } - - private fun resolveTraceSampleRate(datadogContext: DatadogContext): Float? { - val tracingContext = datadogContext.featuresContext[Feature.TRACING_FEATURE_NAME] - return tracingContext?.get(TRACE_SAMPLE_RATE) as? Float - } - private fun resolveErrorProfilingStatus(datadogContext: DatadogContext): ErrorEvent.Profiling? { val isRunning = datadogContext.isProfilerRunning() val quotaReason = datadogContext.resolveProfilingQuotaReason(sessionId) diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt index e50d088f44..e991999878 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt @@ -9,73 +9,53 @@ package com.datadog.android.rum.internal.timeseries import androidx.annotation.WorkerThread import com.datadog.android.api.InternalLogger import com.datadog.android.core.internal.utils.scheduleSafe +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.domain.scope.RumViewType import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit -/** - * Per-session timeseries collector. - * - * Lifecycle: - * - Each instance is single-use: exactly one [onSessionStart] followed by exactly one [onSessionStop]. - * Duplicate calls are no-ops, and `RumSessionScope` builds a fresh instance per session. - * - [onViewTypeUpdate] is only meaningful between those two calls. - * - * Foreground gating: - * - Sampling only runs while the app is in the foreground, so [onSessionStart] starts a sampling - * chain only when the session begins on a foreground view. - * - Leaving the foreground schedules a deferred suspension which flushes whatever is buffered, so - * the pending batch reaches the writer instead of being dropped when the app is backgrounded. - * - Returning to the foreground cancels a suspension that has not fired yet, or starts a fresh - * sampling generation if it already did. - * - * Threading: - * - [onSessionStart] / [onSessionStop] / [onViewTypeUpdate] are called from the RUM event-handler thread. - * - Sampling and suspension tasks run on a [scheduledExecutorService] shared with other RUM - * components (owned by the SDK core); the instance neither owns nor shuts it down. - * - Access to a [Pipeline] is serialized on the pipeline instance, so a flush from the suspension - * task cannot interleave with a sampling tick. - * - Duplicate-chain prevention: each sampling chain carries a generation number. When a new - * generation starts, in-flight or queued ticks from the previous one self-terminate on their - * first check. - */ internal class DefaultTimeseriesCollector( private val internalLogger: InternalLogger, internal val pipelines: List>, internal val scheduledExecutorService: ScheduledExecutorService, - @Volatile private var currentViewType: RumViewType? + @Volatile private var rumContext: RumContext ) : TimeseriesCollector { - private val state = State() + // Batches are attributed to the view they are sent from, but a flush can happen once the app + // already left the foreground, where there is no view to attribute to. Keep the last foreground + // context so those batches stay attached to the view they were sent from. + @Volatile + private var lastForegroundRumContext: RumContext = rumContext + @Volatile private var recentSuspension: ScheduledFuture<*>? = null // region PUBLIC API - @WorkerThread override fun onSessionStart() { - state.set(isActive = currentViewType.isForeground)?.let { generation -> scheduleSampling(generation) } + state.set(isActive = rumContext.viewType.isForeground)?.let { generation -> scheduleSampling(generation) } } @WorkerThread override fun onSessionStop() { cancelSuspension() if (state.set(false) != null) { - flushPipelines() + flushPipelines(lastForegroundRumContext) } } @WorkerThread - override fun onViewTypeUpdate(newViewType: RumViewType) { - val oldViewType = currentViewType - if (newViewType == oldViewType) return + override fun onRumContextUpdate(newRumContext: RumContext) { + val oldViewType = rumContext.viewType + val newViewType = newRumContext.viewType val isEnterForeground = !oldViewType.isForeground && newViewType.isForeground val isLeaveForeground = oldViewType.isForeground && !newViewType.isForeground - currentViewType = newViewType + rumContext = newRumContext + if (newViewType.isForeground) lastForegroundRumContext = newRumContext if (isLeaveForeground) { scheduleStop(state.currentGeneration) @@ -86,7 +66,7 @@ internal class DefaultTimeseriesCollector( // endregion - // region SAMPLING + //region SAMPLING private fun scheduleSampling(generation: Int) { cancelSuspension() @@ -105,10 +85,9 @@ internal class DefaultTimeseriesCollector( ) { if (!state.isGenerationActive(generation)) return@scheduleSafe try { - // The chain stays alive during the suspension delay, so a tick landing while the - // app is already out of the foreground must skip the sample but keep the chain. - if (currentViewType.isForeground) { - synchronized(pipeline) { pipeline.execute() } + val currentRumContext = rumContext + if (currentRumContext.viewType.isForeground) { + pipeline.execute(currentRumContext) } } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { internalLogger.log( @@ -124,10 +103,10 @@ internal class DefaultTimeseriesCollector( } @WorkerThread - private fun flushPipelines() { + private fun flushPipelines(rumContext: RumContext) { pipelines.forEach { pipeline -> try { - synchronized(pipeline, pipeline::flush) + pipeline.flush(rumContext) } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { internalLogger.log( level = InternalLogger.Level.ERROR, @@ -150,8 +129,8 @@ internal class DefaultTimeseriesCollector( TimeUnit.MILLISECONDS, internalLogger ) { - if (!currentViewType.isForeground && state.stopGeneration(stopRequestGeneration)) { - flushPipelines() + if (!rumContext.viewType.isForeground && state.stopGeneration(stopRequestGeneration)) { + flushPipelines(lastForegroundRumContext) } } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt index 218a681151..f8018c0105 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt @@ -7,29 +7,111 @@ package com.datadog.android.rum.internal.timeseries import com.datadog.android.api.InternalLogger +import com.datadog.android.api.feature.FeatureSdkCore +import com.datadog.android.api.storage.DataWriter import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.domain.scope.RumViewType +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector +import com.datadog.android.rum.internal.timeseries.factory.CpuEventFactory +import com.datadog.android.rum.internal.timeseries.factory.MemoryEventFactory +import com.datadog.android.rum.internal.timeseries.provider.CpuDatapointReader +import com.datadog.android.rum.internal.timeseries.provider.VitalReaderWrapper +import com.datadog.android.rum.internal.vitals.CpuStatReader +import com.datadog.android.rum.internal.vitals.MemoryVitalReader +import com.datadog.android.rum.timeseries.TimeseriesConfiguration +import com.datadog.android.rum.timeseries.TimeseriesType import java.util.concurrent.ScheduledExecutorService +@Suppress("LongParameterList") internal class DefaultTimeseriesCollectorFactory( - private val internalLogger: InternalLogger, + private val sdkCore: FeatureSdkCore, + private val configuration: TimeseriesConfiguration, private val scheduledExecutorService: ScheduledExecutorService, - private val pipelinesProvider: ( - applicationId: String, - sessionId: String, - sessionType: RumSessionType - ) -> List> + private val insightsCollector: InsightsCollector, + private val totalRamBytes: Long, + private val dataWriter: DataWriter, + private val batteryInfoProvider: InfoProvider, + private val displayInfoProvider: InfoProvider ) : TimeseriesCollector.Factory { override fun create( - applicationId: String, - sessionId: String, sessionType: RumSessionType, - viewType: RumViewType? - ) = DefaultTimeseriesCollector( - internalLogger = internalLogger, - scheduledExecutorService = scheduledExecutorService, - currentViewType = viewType, - pipelines = pipelinesProvider(applicationId, sessionId, sessionType) + rumContext: RumContext, + customAttributes: () -> Map + ): TimeseriesCollector { + val pipelines = mutableListOf>() + + if (TimeseriesType.CPU in configuration.enabledTypes) { + pipelines += createCpuPipeline(sessionType, customAttributes) + } + + if (TimeseriesType.MEMORY in configuration.enabledTypes) { + if (totalRamBytes > 0L) { + pipelines += createMemoryPipeline(sessionType, customAttributes) + } else { + sdkCore.internalLogger.log( + InternalLogger.Level.WARN, + InternalLogger.Target.USER, + { MEMORY_TIMESERIES_DISABLED_MESSAGE }, + onlyOnce = true + ) + } + } + + return DefaultTimeseriesCollector( + internalLogger = sdkCore.internalLogger, + scheduledExecutorService = scheduledExecutorService, + rumContext = rumContext, + pipelines = pipelines + ) + } + + private fun createMemoryPipeline(sessionType: RumSessionType, customAttributes: () -> Map) = Pipeline( + sdkCore = sdkCore, + reader = VitalReaderWrapper( + vitalReader = MemoryVitalReader(internalLogger = sdkCore.internalLogger), + timeProvider = sdkCore.timeProvider, + intervalMs = TimeseriesConfiguration.DEFAULT_INTERVAL_MS + ), + buffer = Buffer(TimeseriesConfiguration.DEFAULT_BUFFER_SIZE), + eventFactory = MemoryEventFactory( + sessionType = sessionType, + totalRamBytes = totalRamBytes, + timeProvider = sdkCore.timeProvider, + batteryInfoProvider = batteryInfoProvider, + displayInfoProvider = displayInfoProvider, + internalLogger = sdkCore.internalLogger + ), + dataWriter = dataWriter, + customAttributes = customAttributes, + insightsCollector = insightsCollector ) + + private fun createCpuPipeline(sessionType: RumSessionType, customAttributes: () -> Map) = Pipeline( + sdkCore = sdkCore, + reader = CpuDatapointReader( + cpuStatReader = CpuStatReader(internalLogger = sdkCore.internalLogger), + timeProvider = sdkCore.timeProvider, + intervalMs = TimeseriesConfiguration.DEFAULT_INTERVAL_MS + ), + buffer = Buffer(TimeseriesConfiguration.DEFAULT_BUFFER_SIZE), + eventFactory = CpuEventFactory( + sessionType = sessionType, + timeProvider = sdkCore.timeProvider, + batteryInfoProvider = batteryInfoProvider, + displayInfoProvider = displayInfoProvider, + internalLogger = sdkCore.internalLogger + ), + dataWriter = dataWriter, + customAttributes = customAttributes, + insightsCollector = insightsCollector + ) + + internal companion object { + const val MEMORY_TIMESERIES_DISABLED_MESSAGE = + "Unable to read total device memory; memory timeseries collection is disabled." + } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Pipeline.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Pipeline.kt index 3edeafd402..9dc7aa77ad 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Pipeline.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/Pipeline.kt @@ -14,44 +14,59 @@ import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter import com.datadog.android.api.storage.EventType +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector import com.datadog.android.rum.internal.instrumentation.insights.NoOpInsightsCollector +import com.datadog.android.rum.internal.timeseries.factory.EventFactory import com.datadog.android.rum.internal.timeseries.provider.DataPointsReader -import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer -import com.datadog.android.rum.internal.timeseries.serializer.TimeseriesAttributes -import com.google.gson.JsonObject @Suppress("LongParameterList") internal class Pipeline( private val sdkCore: FeatureSdkCore, private val reader: DataPointsReader, private val buffer: Buffer, - private val serializer: JsonSerializer, + private val eventFactory: EventFactory, private val dataWriter: DataWriter, - private val internalLogger: InternalLogger, + private val customAttributes: () -> Map, private val insightsCollector: InsightsCollector = NoOpInsightsCollector() ) { val intervalMs: Long get() = reader.intervalMs @WorkerThread - fun execute() { - reader.read()?.let(buffer::add) - if (buffer.isFull()) flush() + fun execute(rumContext: RumContext) { + // reader.read() may hit the filesystem (/proc); kept outside the lock so a concurrent + // flush() waits only for the buffer and never for I/O. + val dataPoint = reader.read() + synchronized(this) { + dataPoint?.let(buffer::add) + if (buffer.isFull()) drainAndWrite(rumContext) + } } @WorkerThread - fun flush() { + fun flush(rumContext: RumContext) = synchronized(this) { drainAndWrite(rumContext) } + + private fun drainAndWrite(rumContext: RumContext) { val dataPoints = buffer.drain().ifEmpty { return } + // Snapshotted here and not at serialization time: serialization runs later on the core + // context thread, by then the RUM monitor owning those attributes may already be + // unregistered, and the provider hands out the live global attribute map. + val attributes = customAttributes().toMap() sdkCore.getFeature(Feature.RUM_FEATURE_NAME) - ?.withWriteContext { datadogContext: DatadogContext, writeScope: EventWriteScope -> - val json = safeCall(ERROR_SERIALIZATION_FAILED) { - serializer.serialize(datadogContext, dataPoints) + ?.withWriteContext( + withFeatureContexts = setOf( + Feature.SESSION_REPLAY_FEATURE_NAME, + Feature.TRACING_FEATURE_NAME + ) + ) { datadogContext: DatadogContext, writeScope: EventWriteScope -> + val event = safeCall(ERROR_EVENT_CREATION_FAILED) { + eventFactory.create(datadogContext, rumContext, dataPoints, attributes) } ?: return@withWriteContext writeScope { batchWriter -> safeCall(ERROR_FLUSH_FAILED) { - if (dataWriter.write(batchWriter, json, EventType.DEFAULT)) { - insightsCollector.onTimeseries(json.timeseriesName) + if (dataWriter.write(batchWriter, event, EventType.DEFAULT)) { + insightsCollector.onTimeseries(eventFactory.eventName) } } } @@ -61,7 +76,7 @@ internal class Pipeline( private inline fun safeCall(message: String, block: () -> R): R? = try { block() } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { - internalLogger.log( + sdkCore.internalLogger.log( level = InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), messageBuilder = { message }, @@ -72,10 +87,6 @@ internal class Pipeline( private companion object { private const val ERROR_FLUSH_FAILED = "Timeseries flush failed" - private const val ERROR_SERIALIZATION_FAILED = "Timeseries serialization failed" - private val JsonObject.timeseriesName: String - get() = getAsJsonObject(TimeseriesAttributes.KEY_TIMESERIES) - ?.get(TimeseriesAttributes.KEY_NAME) - ?.asString.orEmpty() + private const val ERROR_EVENT_CREATION_FAILED = "Timeseries event creation failed" } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt index 2fd568dc57..40c8ba7a1d 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/TimeseriesCollector.kt @@ -7,22 +7,21 @@ package com.datadog.android.rum.internal.timeseries import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.domain.scope.RumViewType +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.tools.annotation.NoOpImplementation @NoOpImplementation internal interface TimeseriesCollector { fun onSessionStart() fun onSessionStop() - fun onViewTypeUpdate(newViewType: RumViewType) + fun onRumContextUpdate(newRumContext: RumContext) @NoOpImplementation interface Factory { fun create( - applicationId: String, - sessionId: String, sessionType: RumSessionType, - viewType: RumViewType? + rumContext: RumContext, + customAttributes: () -> Map ): TimeseriesCollector } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactory.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactory.kt new file mode 100644 index 0000000000..4acafc2970 --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactory.kt @@ -0,0 +1,111 @@ +/* + * 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.rum.internal.timeseries.factory + +import com.datadog.android.api.InternalLogger +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.core.internal.utils.DdTagsUtils +import com.datadog.android.internal.time.TimeProvider +import com.datadog.android.rum.RumSessionType +import com.datadog.android.rum.internal.FeaturesContextResolver +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.domain.scope.resolveSessionReplaySampleRate +import com.datadog.android.rum.internal.domain.scope.resolveTraceSampleRate +import com.datadog.android.rum.internal.domain.scope.toTimeseriesCpuDevice +import com.datadog.android.rum.internal.domain.scope.toTimeseriesCpuOs +import com.datadog.android.rum.internal.domain.scope.toTimeseriesCpuSessionPrecondition +import com.datadog.android.rum.internal.domain.scope.tryFromSource +import com.datadog.android.rum.internal.timeseries.DataPoint +import com.datadog.android.rum.internal.toTimeseriesCpuSessionType +import com.datadog.android.rum.model.TimeseriesCpuEvent +import java.util.UUID + +@Suppress("LongParameterList") +internal class CpuEventFactory( + private val sessionType: RumSessionType, + private val timeProvider: TimeProvider, + private val batteryInfoProvider: InfoProvider, + private val displayInfoProvider: InfoProvider, + private val internalLogger: InternalLogger, + private val featuresContextResolver: FeaturesContextResolver = FeaturesContextResolver() +) : EventFactory { + + override val eventName: String = "cpu" + + @Suppress("LongMethod") + override fun create( + datadogContext: DatadogContext, + rumContext: RumContext, + dataPoints: List>, + customAttributes: Map + ): TimeseriesCpuEvent? { + if (dataPoints.isEmpty()) return null + + val deviceInfo = datadogContext.deviceInfo + val syntheticsAttribute = if ( + rumContext.syntheticsTestId.isNullOrBlank() || + rumContext.syntheticsResultId.isNullOrBlank() + ) { + null + } else { + TimeseriesCpuEvent.Synthetics( + testId = rumContext.syntheticsTestId, + resultId = rumContext.syntheticsResultId + ) + } + + return TimeseriesCpuEvent( + dd = TimeseriesCpuEvent.Dd( + session = TimeseriesCpuEvent.DdSession( + sessionPrecondition = rumContext.sessionStartReason.toTimeseriesCpuSessionPrecondition() + ), + configuration = TimeseriesCpuEvent.Configuration( + sessionSampleRate = rumContext.sessionSampleRate, + sessionReplaySampleRate = datadogContext.resolveSessionReplaySampleRate(), + traceSampleRate = datadogContext.resolveTraceSampleRate() + ) + ), + application = TimeseriesCpuEvent.Application( + id = rumContext.applicationId, + currentLocale = deviceInfo.localeInfo.currentLocale + ), + session = TimeseriesCpuEvent.TimeseriesCpuEventSession( + id = rumContext.sessionId, + type = sessionType.toTimeseriesCpuSessionType(), + hasReplay = featuresContextResolver.resolveViewHasReplay( + datadogContext, + rumContext.viewId.orEmpty() + ) + ), + synthetics = syntheticsAttribute, + source = TimeseriesCpuEvent.Source.tryFromSource(datadogContext.source, internalLogger), + date = timeProvider.getServerTimestampMillis(), + version = datadogContext.version, + service = datadogContext.service, + buildVersion = datadogContext.versionCode.toString(), + buildId = datadogContext.appBuildId, + ddtags = DdTagsUtils.toDdTagsString(datadogContext), + os = deviceInfo.toTimeseriesCpuOs(), + device = deviceInfo.toTimeseriesCpuDevice( + batteryInfo = batteryInfoProvider.getState(), + displayInfo = displayInfoProvider.getState() + ), + timeseries = TimeseriesCpuEvent.Timeseries( + id = UUID.randomUUID().toString(), + start = dataPoints.firstOrNull()?.timestampNs ?: 0L, + end = dataPoints.lastOrNull()?.timestampNs ?: 0L, + data = TimeseriesCpuEvent.Data( + timestamps = dataPoints.map { it.timestampNs }, + values = TimeseriesCpuEvent.Values(dataPoints.map { it.value }) + ) + ) + ) + } +} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/EventFactory.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/EventFactory.kt new file mode 100644 index 0000000000..92464a7bb6 --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/EventFactory.kt @@ -0,0 +1,22 @@ +/* + * 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.rum.internal.timeseries.factory + +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.timeseries.DataPoint + +internal interface EventFactory { + val eventName: String + + fun create( + datadogContext: DatadogContext, + rumContext: RumContext, + dataPoints: List>, + customAttributes: Map + ): E? +} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactory.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactory.kt new file mode 100644 index 0000000000..7e7c5d4c66 --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactory.kt @@ -0,0 +1,124 @@ +/* + * 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.rum.internal.timeseries.factory + +import com.datadog.android.api.InternalLogger +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.core.internal.utils.DdTagsUtils +import com.datadog.android.internal.time.TimeProvider +import com.datadog.android.rum.RumSessionType +import com.datadog.android.rum.internal.FeaturesContextResolver +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.domain.scope.resolveSessionReplaySampleRate +import com.datadog.android.rum.internal.domain.scope.resolveTraceSampleRate +import com.datadog.android.rum.internal.domain.scope.toTimeseriesMemoryDevice +import com.datadog.android.rum.internal.domain.scope.toTimeseriesMemoryOs +import com.datadog.android.rum.internal.domain.scope.toTimeseriesMemorySessionPrecondition +import com.datadog.android.rum.internal.domain.scope.tryFromSource +import com.datadog.android.rum.internal.timeseries.DataPoint +import com.datadog.android.rum.internal.toTimeseriesMemorySessionType +import com.datadog.android.rum.model.TimeseriesMemoryEvent +import java.util.UUID + +@Suppress("LongParameterList") +internal class MemoryEventFactory( + private val sessionType: RumSessionType, + private val totalRamBytes: Long, + private val timeProvider: TimeProvider, + private val batteryInfoProvider: InfoProvider, + private val displayInfoProvider: InfoProvider, + private val internalLogger: InternalLogger, + private val featuresContextResolver: FeaturesContextResolver = FeaturesContextResolver() +) : EventFactory { + + override val eventName: String = "memory" + + @Suppress("LongMethod") + override fun create( + datadogContext: DatadogContext, + rumContext: RumContext, + dataPoints: List>, + customAttributes: Map + ): TimeseriesMemoryEvent? { + if (totalRamBytes <= 0L || dataPoints.isEmpty()) return null + + val deviceInfo = datadogContext.deviceInfo + val syntheticsAttribute = if ( + rumContext.syntheticsTestId.isNullOrBlank() || + rumContext.syntheticsResultId.isNullOrBlank() + ) { + null + } else { + TimeseriesMemoryEvent.Synthetics( + testId = rumContext.syntheticsTestId, + resultId = rumContext.syntheticsResultId + ) + } + + return TimeseriesMemoryEvent( + dd = TimeseriesMemoryEvent.Dd( + session = TimeseriesMemoryEvent.DdSession( + sessionPrecondition = rumContext.sessionStartReason.toTimeseriesMemorySessionPrecondition() + ), + configuration = TimeseriesMemoryEvent.Configuration( + sessionSampleRate = rumContext.sessionSampleRate, + sessionReplaySampleRate = datadogContext.resolveSessionReplaySampleRate(), + traceSampleRate = datadogContext.resolveTraceSampleRate() + ) + ), + application = TimeseriesMemoryEvent.Application( + id = rumContext.applicationId, + currentLocale = deviceInfo.localeInfo.currentLocale + ), + session = TimeseriesMemoryEvent.TimeseriesMemoryEventSession( + id = rumContext.sessionId, + type = sessionType.toTimeseriesMemorySessionType(), + hasReplay = featuresContextResolver.resolveViewHasReplay( + datadogContext, + rumContext.viewId.orEmpty() + ) + ), + synthetics = syntheticsAttribute, + source = TimeseriesMemoryEvent.Source.tryFromSource(datadogContext.source, internalLogger), + date = timeProvider.getServerTimestampMillis(), + version = datadogContext.version, + service = datadogContext.service, + buildVersion = datadogContext.versionCode.toString(), + buildId = datadogContext.appBuildId, + ddtags = DdTagsUtils.toDdTagsString(datadogContext), + os = deviceInfo.toTimeseriesMemoryOs(), + device = deviceInfo.toTimeseriesMemoryDevice( + batteryInfo = batteryInfoProvider.getState(), + displayInfo = displayInfoProvider.getState() + ), + timeseries = TimeseriesMemoryEvent.Timeseries( + id = UUID.randomUUID().toString(), + start = dataPoints.firstOrNull()?.timestampNs ?: 0L, + end = dataPoints.lastOrNull()?.timestampNs ?: 0L, + data = TimeseriesMemoryEvent.Data( + timestamps = dataPoints.map { it.timestampNs }, + values = TimeseriesMemoryEvent.Values( + memoryPercent = dataPoints.map { it.value / totalRamBytes * PERCENT_FACTOR }, + memoryFootprint = dataPoints.map { it.value / BYTES_IN_KB } + ) + ) + ) + ) + } + + private companion object { + const val PERCENT_FACTOR = 100.0 + + // Must match the factor used in MemoryVitalReader when converting VmRSS kB to bytes. + // Datadog memory vitals use decimal (SI) units, so 1000 (not 1024) keeps the emitted + // memory_footprint consistent with the collected value and with memory_percent. + const val BYTES_IN_KB = 1000 + } +} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReader.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReader.kt index d48d4fe76f..efcf4a1dde 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReader.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReader.kt @@ -22,20 +22,24 @@ import com.datadog.android.rum.internal.vitals.CpuStatReader */ internal class CpuDatapointReader( private val cpuStatReader: CpuStatReader, - private val cpuTimeProvider: TimeProvider, + private val timeProvider: TimeProvider, override val intervalMs: Long, private val availableProcessors: Int = Runtime.getRuntime().availableProcessors() -) : DataPointsReader(cpuTimeProvider) { +) : DataPointsReader(timeProvider) { private var lastUtime: Double? = null private var lastNs: Long? = null @WorkerThread override fun readValue() = cpuStatReader.readActiveTime()?.let { currentCpuTicks -> - val nowNs = cpuTimeProvider.getDeviceElapsedTimeNanos() + val nowNs = timeProvider.getDeviceElapsedTimeNanos() val (prevCpuTicks, prevNs) = updateValues(currentCpuTicks, nowNs) if (prevCpuTicks == null || prevNs == null) return null val elapsedMs = ((nowNs - prevNs) / NS_PER_MS).coerceAtLeast(1L) + // Sampling is suspended while the app is not in the foreground, so a gap much longer than + // the sampling interval means this delta spans that pause and would smear background CPU + // time over the first foreground sample. Drop it; the read above already re-baselined. + if (elapsedMs > intervalMs * MAX_GAP_FACTOR) return null val corePercent = (currentCpuTicks - prevCpuTicks) * MS_PER_SECOND / elapsedMs (corePercent / availableProcessors.coerceAtLeast(1)).coerceIn(0.0, MAX_CPU_PERCENT) } @@ -55,5 +59,8 @@ internal class CpuDatapointReader( private const val MS_PER_SECOND = 1000.0 private const val NS_PER_MS = 1_000_000L private const val MAX_CPU_PERCENT = 100.0 + + // How many sampling intervals a delta may span before it is treated as a gap. + internal const val MAX_GAP_FACTOR = 2 } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/DataPointsReader.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/DataPointsReader.kt index f936571168..d00bb7bbce 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/DataPointsReader.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/provider/DataPointsReader.kt @@ -22,7 +22,7 @@ internal abstract class DataPointsReader(private val timeProvider: Time open fun read(): DataPoint? = readValue()?.let { value -> DataPoint( value = value, - timestampNs = TimeUnit.MILLISECONDS.toNanos(timeProvider.getDeviceTimestampMillis()) + timestampNs = TimeUnit.MILLISECONDS.toNanos(timeProvider.getServerTimestampMillis()) ) } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializer.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializer.kt deleted file mode 100644 index 64d7fdf040..0000000000 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializer.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.rum.internal.timeseries.serializer - -import com.datadog.android.api.context.DatadogContext -import com.datadog.android.internal.time.TimeProvider -import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.timeseries.DataPoint -import com.datadog.android.rum.internal.toTimeseriesCpuSessionType -import com.datadog.android.rum.model.TimeseriesCpuEvent -import com.google.gson.JsonObject -import java.util.UUID - -@Suppress("LongParameterList") -internal class CpuEventSerializer( - private val sessionId: String, - private val applicationId: String, - private val sessionType: RumSessionType, - private val timeProvider: TimeProvider -) : JsonSerializer { - - override fun serialize(datadogContext: DatadogContext, dataPoints: List>): JsonObject? { - if (dataPoints.isEmpty()) return null - return TimeseriesCpuEvent( - dd = TimeseriesCpuEvent.Dd(), - application = TimeseriesCpuEvent.Application(id = applicationId), - session = TimeseriesCpuEvent.Session(id = sessionId, type = sessionType.toTimeseriesCpuSessionType()), - source = TimeseriesCpuEvent.Source.ANDROID, - date = timeProvider.getDeviceTimestampMillis(), - version = datadogContext.version, - service = datadogContext.service, - timeseries = TimeseriesCpuEvent.Timeseries( - id = UUID.randomUUID().toString(), - start = dataPoints.firstOrNull()?.timestampNs ?: 0L, - end = dataPoints.lastOrNull()?.timestampNs ?: 0L, - data = TimeseriesCpuEvent.Data( - timestamps = dataPoints.map { it.timestampNs }, - values = TimeseriesCpuEvent.Values(dataPoints.map { it.value }) - ) - ) - ).toJson().asJsonObject - } -} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializer.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializer.kt deleted file mode 100644 index 7d9d1c4708..0000000000 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializer.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.rum.internal.timeseries.serializer - -import com.datadog.android.api.context.DatadogContext -import com.datadog.android.internal.time.TimeProvider -import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.timeseries.DataPoint -import com.datadog.android.rum.internal.toTimeseriesMemorySessionType -import com.datadog.android.rum.model.TimeseriesMemoryEvent -import com.google.gson.JsonObject -import java.util.UUID - -@Suppress("LongParameterList") -internal class MemoryEventSerializer( - private val sessionId: String, - private val applicationId: String, - private val sessionType: RumSessionType, - private val totalRamBytes: Long, - private val timeProvider: TimeProvider -) : JsonSerializer { - - override fun serialize(datadogContext: DatadogContext, dataPoints: List>): JsonObject? { - if (totalRamBytes <= 0L || dataPoints.isEmpty()) return null - return TimeseriesMemoryEvent( - dd = TimeseriesMemoryEvent.Dd(), - application = TimeseriesMemoryEvent.Application(id = applicationId), - session = TimeseriesMemoryEvent.Session(id = sessionId, type = sessionType.toTimeseriesMemorySessionType()), - source = TimeseriesMemoryEvent.Source.ANDROID, - date = timeProvider.getDeviceTimestampMillis(), - version = datadogContext.version, - service = datadogContext.service, - timeseries = TimeseriesMemoryEvent.Timeseries( - id = UUID.randomUUID().toString(), - start = dataPoints.firstOrNull()?.timestampNs ?: 0L, - end = dataPoints.lastOrNull()?.timestampNs ?: 0L, - data = TimeseriesMemoryEvent.Data( - timestamps = dataPoints.map { it.timestampNs }, - values = TimeseriesMemoryEvent.Values( - memoryPercent = dataPoints.map { it.value / totalRamBytes * PERCENT_FACTOR }, - memoryFootprint = dataPoints.map { it.value / BYTES_IN_KB } - ) - ) - ) - ).toJson().asJsonObject - } - - private companion object { - const val PERCENT_FACTOR = 100.0 - - // Must match the factor used in MemoryVitalReader when converting VmRSS kB to bytes. - // Datadog memory vitals use decimal (SI) units, so 1000 (not 1024) keeps the emitted - // memory_footprint consistent with the collected value and with memory_percent. - const val BYTES_IN_KB = 1000 - } -} diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/JsonSerializer.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/TimeseriesAttributes.kt similarity index 61% rename from features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/JsonSerializer.kt rename to features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/TimeseriesAttributes.kt index c796d28f4c..fbdefdc52b 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/JsonSerializer.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/serializer/TimeseriesAttributes.kt @@ -6,14 +6,6 @@ package com.datadog.android.rum.internal.timeseries.serializer -import com.datadog.android.api.context.DatadogContext -import com.datadog.android.rum.internal.timeseries.DataPoint -import com.google.gson.JsonObject - -internal fun interface JsonSerializer { - fun serialize(datadogContext: DatadogContext, dataPoints: List>): JsonObject? -} - internal object TimeseriesAttributes { const val KEY_TIMESERIES = "timeseries" const val KEY_SCHEMA = "schema" diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt index d60314638a..58c8a70d58 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfiguration.kt @@ -5,11 +5,7 @@ */ package com.datadog.android.rum.timeseries -import androidx.annotation.IntRange import com.datadog.android.rum.ExperimentalRumApi -import com.datadog.android.rum.timeseries.TimeseriesConfiguration.Companion.DEFAULT_BUFFER_SIZE -import com.datadog.android.rum.timeseries.TimeseriesConfiguration.Companion.DEFAULT_INTERVAL_MS -import com.datadog.android.rum.timeseries.TimeseriesConfiguration.Companion.MIN_INTERVAL_MS /** * Configuration for memory and CPU timeseries collection. @@ -17,8 +13,7 @@ import com.datadog.android.rum.timeseries.TimeseriesConfiguration.Companion.MIN_ * Use [Builder] to create an instance. */ class TimeseriesConfiguration internal constructor( - internal val bufferSize: Int, - internal val intervalMs: Long + internal val enabledTypes: Set ) { /** @@ -27,35 +22,25 @@ class TimeseriesConfiguration internal constructor( @ExperimentalRumApi class Builder { - private var bufferSize: Int = DEFAULT_BUFFER_SIZE - private var intervalMs: Long = DEFAULT_INTERVAL_MS + @Suppress("UnsafeThirdPartyFunctionCall") // Kotlin Array.toSet() is safe for enum values. + private var enabledTypes: Set = TimeseriesType.values().toSet() /** - * Sets the number of samples accumulated per pipeline before sending a batch event. - * Must be > 0; out-of-range values fall back to [DEFAULT_BUFFER_SIZE]. - * Defaults to [DEFAULT_BUFFER_SIZE] (≈120 seconds at the default 1 s interval). + * Restricts collection to the provided timeseries types. + * + * By default, all supported timeseries types are collected. + * Passing an empty array disables collection of every timeseries type. + * + * @param types the timeseries types to collect. */ - fun setBufferSize( - @IntRange(from = 1, to = Int.MAX_VALUE.toLong()) bufferSize: Int - ): Builder = apply { - this.bufferSize = if (bufferSize > 0) bufferSize else DEFAULT_BUFFER_SIZE - } - - /** - * Sets the sampling interval in milliseconds. - * Must be ≥ [MIN_INTERVAL_MS]; out-of-range values fall back to [DEFAULT_INTERVAL_MS]. - * Defaults to [DEFAULT_INTERVAL_MS]. - */ - fun setIntervalMs( - @IntRange(from = MIN_INTERVAL_MS, to = Long.MAX_VALUE) intervalMs: Long - ): Builder = apply { - this.intervalMs = if (intervalMs >= MIN_INTERVAL_MS) intervalMs else DEFAULT_INTERVAL_MS + fun collectOnly(vararg types: TimeseriesType): Builder = apply { + @Suppress("UnsafeThirdPartyFunctionCall") // Kotlin Array.toSet() is safe for enum values. + enabledTypes = types.toSet() } /** Builds a [TimeseriesConfiguration] from the current builder state. */ fun build(): TimeseriesConfiguration = TimeseriesConfiguration( - bufferSize = bufferSize, - intervalMs = intervalMs + enabledTypes = enabledTypes ) } @@ -70,8 +55,5 @@ class TimeseriesConfiguration internal constructor( /** Default sampling interval in milliseconds. */ internal const val DEFAULT_INTERVAL_MS: Long = 1000L - - /** Minimum allowed sampling interval in milliseconds. */ - internal const val MIN_INTERVAL_MS: Long = 100L } } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesType.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesType.kt new file mode 100644 index 0000000000..56e41ee01a --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/timeseries/TimeseriesType.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.rum.timeseries + +/** + * Type of device timeseries that can be collected by RUM. + */ +enum class TimeseriesType { + + /** CPU usage timeseries. */ + CPU, + + /** Memory usage timeseries. */ + MEMORY +} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/RumConfigurationBuilderTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/RumConfigurationBuilderTest.kt index 05fb33144c..b9be98d4a3 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/RumConfigurationBuilderTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/RumConfigurationBuilderTest.kt @@ -31,6 +31,7 @@ import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent import com.datadog.android.rum.timeseries.TimeseriesConfiguration +import com.datadog.android.rum.timeseries.TimeseriesType import com.datadog.android.rum.tracking.ActionTrackingStrategy import com.datadog.android.rum.tracking.ActivityViewTrackingStrategy import com.datadog.android.rum.tracking.InteractionPredicate @@ -743,9 +744,11 @@ internal class RumConfigurationBuilderTest { } @Test - fun `M store provided configuration W setTimeseriesConfiguration(config)`() { + fun `M store provided configuration W setTimeseriesConfiguration(config)`(forge: Forge) { // Given - val fakeConfig = TimeseriesConfiguration.Builder().setBufferSize(10).setIntervalMs(500L).build() + val fakeConfig = TimeseriesConfiguration.Builder() + .collectOnly(forge.aValueFrom(TimeseriesType::class.java)) + .build() // When val rumConfiguration = testedBuilder.setTimeseriesConfiguration(fakeConfig).build() @@ -754,27 +757,4 @@ internal class RumConfigurationBuilderTest { assertThat(rumConfiguration.featureConfiguration.timeseriesConfiguration) .isSameAs(fakeConfig) } - - @Test - fun `M store default configuration W setTimeseriesConfiguration(default)`() { - // When - val rumConfiguration = testedBuilder - .setTimeseriesConfiguration(TimeseriesConfiguration.Builder().build()) - .build() - - // Then - assertThat(rumConfiguration.featureConfiguration.timeseriesConfiguration).isNotNull - } - - @Test - fun `M nullify configuration W setTimeseriesConfiguration(null)`() { - // Given - testedBuilder.setTimeseriesConfiguration(TimeseriesConfiguration.Builder().build()) - - // When - val rumConfiguration = testedBuilder.setTimeseriesConfiguration(null).build() - - // Then - assertThat(rumConfiguration.featureConfiguration.timeseriesConfiguration).isNull() - } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ActionEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ActionEventAssert.kt index 93ab7dc5b9..1c186aa40b 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ActionEventAssert.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ActionEventAssert.kt @@ -157,19 +157,19 @@ internal class ActionEventAssert(actual: ActionEvent) : expectedName: String?, expectedUrl: String? ): ActionEventAssert { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( - "Expected event data to have view.id $expectedId but was ${actual.view.id}" + "Expected event data to have view.id $expectedId but was ${actual.view?.id}" ) .isEqualTo(expectedId.orEmpty()) - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( - "Expected event data to have view.name $expectedName but was ${actual.view.name}" + "Expected event data to have view.name $expectedName but was ${actual.view?.name}" ) .isEqualTo(expectedName) - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( - "Expected event data to have view.url $expectedUrl but was ${actual.view.url}" + "Expected event data to have view.url $expectedUrl but was ${actual.view?.url}" ) .isEqualTo(expectedUrl.orEmpty()) return this @@ -178,21 +178,21 @@ internal class ActionEventAssert(actual: ActionEvent) : fun hasView( expected: RumContext ): ActionEventAssert { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( - "Expected event data to have view.id ${expected.viewId} but was ${actual.view.id}" + "Expected event data to have view.id ${expected.viewId} but was ${actual.view?.id}" ) .isEqualTo(expected.viewId.orEmpty()) - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( "Expected event data to have view.name ${expected.viewName} " + - "but was ${actual.view.name}" + "but was ${actual.view?.name}" ) .isEqualTo(expected.viewName) - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( "Expected event data to have view.url ${expected.viewUrl} " + - "but was ${actual.view.url}" + "but was ${actual.view?.url}" ) .isEqualTo(expected.viewUrl.orEmpty()) return this diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ErrorEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ErrorEventAssert.kt index 2625234924..c7d08d0fe0 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ErrorEventAssert.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ErrorEventAssert.kt @@ -252,41 +252,41 @@ internal class ErrorEventAssert(actual: ErrorEvent) : expectedName: String?, expectedUrl: String? ): ErrorEventAssert { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( - "Expected event data to have view.id $expectedId but was ${actual.view.id}" + "Expected event data to have view.id $expectedId but was ${actual.view?.id}" ) .isEqualTo(expectedId.orEmpty()) - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( - "Expected event data to have view.name $expectedName but was ${actual.view.name}" + "Expected event data to have view.name $expectedName but was ${actual.view?.name}" ) .isEqualTo(expectedName) - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( - "Expected event data to have view.url $expectedUrl but was ${actual.view.url}" + "Expected event data to have view.url $expectedUrl but was ${actual.view?.url}" ) .isEqualTo(expectedUrl.orEmpty()) return this } fun hasView(expected: RumContext): ErrorEventAssert { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( "Expected event data to have view.id ${expected.viewId} " + - "but was ${actual.view.id}" + "but was ${actual.view?.id}" ) .isEqualTo(expected.viewId.orEmpty()) - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( "Expected event data to have view.name ${expected.viewName} " + - "but was ${actual.view.name}" + "but was ${actual.view?.name}" ) .isEqualTo(expected.viewName) - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( "Expected event data to have view.url ${expected.viewUrl} " + - "but was ${actual.view.url}" + "but was ${actual.view?.url}" ) .isEqualTo(expected.viewUrl.orEmpty()) return this diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/LongTaskEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/LongTaskEventAssert.kt index c65cd2807f..143d5f586d 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/LongTaskEventAssert.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/LongTaskEventAssert.kt @@ -180,14 +180,14 @@ internal class LongTaskEventAssert(actual: LongTaskEvent) : } fun hasView(expectedId: String?, expectedUrl: String?): LongTaskEventAssert { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( - "Expected event data to have view.id $expectedId but was ${actual.view.id}" + "Expected event data to have view.id $expectedId but was ${actual.view?.id}" ) .isEqualTo(expectedId.orEmpty()) - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( - "Expected event data to have view.id $expectedUrl but was ${actual.view.url}" + "Expected event data to have view.id $expectedUrl but was ${actual.view?.url}" ) .isEqualTo(expectedUrl.orEmpty()) return this diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ResourceEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ResourceEventAssert.kt index 382c050302..74bfc26d79 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ResourceEventAssert.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/ResourceEventAssert.kt @@ -377,22 +377,22 @@ internal class ResourceEventAssert(actual: ResourceEvent) : } fun hasView(expected: RumContext): ResourceEventAssert { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( "Expected event data to have view.id ${expected.viewId} " + - "but was ${actual.view.id}" + "but was ${actual.view?.id}" ) .isEqualTo(expected.viewId.orEmpty()) - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( "Expected event data to have view.name ${expected.viewName} " + - "but was ${actual.view.name}" + "but was ${actual.view?.name}" ) .isEqualTo(expected.viewName) - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( "Expected event data to have view.url ${expected.viewUrl} " + - "but was ${actual.view.url}" + "but was ${actual.view?.url}" ) .isEqualTo(expected.viewUrl.orEmpty()) return this diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt deleted file mode 100644 index d03fb25d51..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.rum.assertj - -import com.datadog.android.rum.model.TimeseriesCpuEvent -import com.google.gson.JsonObject -import org.assertj.core.api.AbstractObjectAssert -import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.data.Offset -import org.junit.jupiter.api.assertDoesNotThrow -import java.util.UUID - -internal class TimeseriesCpuEventAssert private constructor( - actual: TimeseriesCpuEvent -) : AbstractObjectAssert( - actual, - TimeseriesCpuEventAssert::class.java -) { - - fun hasApplicationId(expected: String): TimeseriesCpuEventAssert = apply { - assertThat(actual.application.id) - .overridingErrorMessage { - "Expected event to have application.id $expected but was ${actual.application.id}" - } - .isEqualTo(expected) - } - - fun hasSessionId(expected: String): TimeseriesCpuEventAssert = apply { - assertThat(actual.session.id) - .overridingErrorMessage { "Expected event to have session.id $expected but was ${actual.session.id}" } - .isEqualTo(expected) - } - - fun hasSessionType(expected: TimeseriesCpuEvent.Type): TimeseriesCpuEventAssert = apply { - assertThat(actual.session.type) - .overridingErrorMessage { "Expected event to have session.type $expected but was ${actual.session.type}" } - .isEqualTo(expected) - } - - fun hasService(expected: String): TimeseriesCpuEventAssert = apply { - assertThat(actual.service) - .overridingErrorMessage { "Expected event to have service $expected but was ${actual.service}" } - .isEqualTo(expected) - } - - fun hasVersion(expected: String): TimeseriesCpuEventAssert = apply { - assertThat(actual.version) - .overridingErrorMessage { "Expected event to have version $expected but was ${actual.version}" } - .isEqualTo(expected) - } - - fun hasDate(expected: Long): TimeseriesCpuEventAssert = apply { - assertThat(actual.date) - .overridingErrorMessage { "Expected event to have date $expected but was ${actual.date}" } - .isEqualTo(expected) - } - - fun hasTimeseriesSchema(expected: String): TimeseriesCpuEventAssert = apply { - assertThat(actual.timeseries.schema) - .overridingErrorMessage { - "Expected event to have timeseries.schema $expected but was ${actual.timeseries.schema}" - } - .isEqualTo(expected) - } - - fun hasTimeseriesStart(expected: Long): TimeseriesCpuEventAssert = apply { - assertThat(actual.timeseries.start) - .overridingErrorMessage { - "Expected event to have timeseries.start $expected but was ${actual.timeseries.start}" - } - .isEqualTo(expected) - } - - fun hasTimeseriesEnd(expected: Long): TimeseriesCpuEventAssert = apply { - assertThat(actual.timeseries.end) - .overridingErrorMessage { - "Expected event to have timeseries.end $expected but was ${actual.timeseries.end}" - } - .isEqualTo(expected) - } - - fun hasValidTimeseriesId(): TimeseriesCpuEventAssert = apply { - assertDoesNotThrow("Expected timeseries.id to be a valid UUID but was ${actual.timeseries.id}") { - UUID.fromString(actual.timeseries.id) - } - } - - fun hasTimeseriesDataCount(expected: Int): TimeseriesCpuEventAssert = apply { - assertThat(actual.timeseries.data.timestamps) - .overridingErrorMessage { - "Expected event to have timeseries.data of size $expected " + - "but was ${actual.timeseries.data.timestamps.size}" - } - .hasSize(expected) - } - - fun hasCpuUsage(expected: Double, offset: Offset, position: Int = 0): TimeseriesCpuEventAssert = apply { - val cpuUsage = actual.timeseries.data.values.cpuUsage.getOrNull(position)?.toDouble() - assertThat(cpuUsage) - .overridingErrorMessage { "Expected first data point cpu_usage to be close to $expected but was $cpuUsage" } - .isNotNull() - .isCloseTo(expected, offset) - } - - companion object { - internal fun assertThat(event: TimeseriesCpuEvent): TimeseriesCpuEventAssert = - TimeseriesCpuEventAssert(event) - - internal fun assertThat(json: JsonObject): TimeseriesCpuEventAssert = - assertThat(TimeseriesCpuEvent.fromJsonObject(json)) - } -} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalAppLaunchEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalAppLaunchEventAssert.kt index e084faddca..f6191dde13 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalAppLaunchEventAssert.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalAppLaunchEventAssert.kt @@ -98,25 +98,25 @@ internal class VitalAppLaunchEventAssert( } fun hasViewId(expectedId: String) = apply { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( - "Expected event data to have view.id $expectedId but was ${actual.view.id}" + "Expected event data to have view.id $expectedId but was ${actual.view?.id}" ) .isEqualTo(expectedId) } fun hasName(expected: String?) = apply { - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( - "Expected event data to have view.name $expected but was ${actual.view.name}" + "Expected event data to have view.name $expected but was ${actual.view?.name}" ) .isEqualTo(expected) } fun hasUrl(expected: String) = apply { - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( - "Expected event data to have view.url $expected but was ${actual.view.url}" + "Expected event data to have view.url $expected but was ${actual.view?.url}" ) .isEqualTo(expected) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalEventAssert.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalEventAssert.kt index 7805c55fb3..6342a6f385 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalEventAssert.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/assertj/VitalEventAssert.kt @@ -107,25 +107,25 @@ internal class VitalEventAssert( } fun hasViewId(expectedId: String) = apply { - assertThat(actual.view.id) + assertThat(actual.view?.id) .overridingErrorMessage( - "Expected event data to have view.id $expectedId but was ${actual.view.id}" + "Expected event data to have view.id $expectedId but was ${actual.view?.id}" ) .isEqualTo(expectedId) } fun hasName(expected: String) = apply { - assertThat(actual.view.name) + assertThat(actual.view?.name) .overridingErrorMessage( - "Expected event data to have view.name $expected but was ${actual.view.name}" + "Expected event data to have view.name $expected but was ${actual.view?.name}" ) .isEqualTo(expected) } fun hasUrl(expected: String) = apply { - assertThat(actual.view.url) + assertThat(actual.view?.url) .overridingErrorMessage( - "Expected event data to have view.url $expected but was ${actual.view.url}" + "Expected event data to have view.url $expected but was ${actual.view?.url}" ) .isEqualTo(expected) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt index 911a74b94e..a01e91dfa7 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt @@ -33,10 +33,8 @@ import com.datadog.android.rum.ExperimentalRumApi import com.datadog.android.rum.GlobalRumMonitor import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource -import com.datadog.android.rum.RumSessionType import com.datadog.android.rum.assertj.RumFeatureAssert import com.datadog.android.rum.configuration.VitalsUpdateFrequency -import com.datadog.android.rum.internal.RumFeature.Companion.MEMORY_TIMESERIES_DISABLED_MESSAGE import com.datadog.android.rum.internal.RumFeature.Companion.SLOW_FRAMES_MONITORING_DISABLED_MESSAGE import com.datadog.android.rum.internal.RumFeature.Companion.SLOW_FRAMES_MONITORING_ENABLED_MESSAGE import com.datadog.android.rum.internal.anr.ANRDetectorRunnable @@ -50,15 +48,14 @@ import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilitySn import com.datadog.android.rum.internal.domain.battery.DefaultBatteryInfoProvider import com.datadog.android.rum.internal.domain.display.DefaultDisplayInfoProvider import com.datadog.android.rum.internal.domain.event.RumEventMapper -import com.datadog.android.rum.internal.domain.scope.RumViewType +import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.monitor.AdvancedRumMonitor import com.datadog.android.rum.internal.monitor.DatadogRumMonitor import com.datadog.android.rum.internal.monitor.NoOpAdvancedRumMonitor import com.datadog.android.rum.internal.startup.RumAppStartupDetector import com.datadog.android.rum.internal.thread.NoOpScheduledExecutorService -import com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollector -import com.datadog.android.rum.internal.timeseries.TimeseriesCollector +import com.datadog.android.rum.internal.timeseries.DefaultTimeseriesCollectorFactory import com.datadog.android.rum.internal.tracking.NoOpInteractionPredicate import com.datadog.android.rum.internal.tracking.NoOpUserActionTrackingStrategy import com.datadog.android.rum.internal.tracking.UserActionTrackingStrategy @@ -860,66 +857,77 @@ internal class RumFeatureTest { } @Test - fun `M flush timeseries before resetting writer W onStop()`() { + fun `M stop active timeseries before resetting writer W onStop()`() { // Given testedFeature.onInitialize(appContext.mockInstance) - val mockDatadogMonitor = mock() + val stubDatadogMonitor = mock() GlobalRumMonitor.clear() - GlobalRumMonitor.registerIfAbsent(mockDatadogMonitor, mockSdkCore) + GlobalRumMonitor.registerIfAbsent(stubDatadogMonitor, mockSdkCore) - var writerAtFlushTime: DataWriter? = null + var writerAtStopTime: DataWriter? = null doAnswer { - writerAtFlushTime = testedFeature.dataWriter - }.whenever(mockDatadogMonitor).stopTimeseries() + writerAtStopTime = testedFeature.dataWriter + }.whenever(stubDatadogMonitor).stopTimeseries() // When testedFeature.onStop() - // Then - assertThat(writerAtFlushTime).isNotNull - assertThat(writerAtFlushTime).isNotInstanceOf(NoOpDataWriter::class.java) + // Then — the last timeseries batch must still reach the real writer + assertThat(writerAtStopTime).isNotNull + assertThat(writerAtStopTime).isNotInstanceOf(NoOpDataWriter::class.java) assertThat(testedFeature.dataWriter).isInstanceOf(NoOpDataWriter::class.java) } @Test - fun `M log USER message W timeseries create() { total RAM unavailable }`( - @StringForgery fakeSessionId: String + @OptIn(ExperimentalRumApi::class) + fun `M wire timeseries factory W initialize { timeseries enabled }`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long ) { - // When - createTimeseries(totalRamBytes = 0L, sessionId = fakeSessionId) - - // Then - mockInternalLogger.verifyLog( - InternalLogger.Level.WARN, - InternalLogger.Target.USER, - MEMORY_TIMESERIES_DISABLED_MESSAGE, - onlyOnce = true + // Given + fakeConfiguration = fakeConfiguration.copy( + timeseriesConfiguration = TimeseriesConfiguration.Builder().build() ) - } - - @Test - fun `M not collect memory W timeseries create() { total RAM unavailable }`( - @StringForgery fakeSessionId: String - ) { - // When - val timeseries = createTimeseries(totalRamBytes = 0L, sessionId = fakeSessionId) - - // Then: only the CPU pipeline is created; the memory pipeline is skipped. - check(timeseries is DefaultTimeseriesCollector) - assertThat(timeseries.pipelines).hasSize(1) - } + testedFeature = RumFeature( + mockSdkCore, + fakeApplicationId.toString(), + fakeConfiguration, + lateCrashReporterFactory = { mockLateCrashReporter } + ) + val stubActivityManager = mock() + doAnswer { invocation -> + invocation.getArgument(0).totalMem = fakeTotalRamBytes + null + }.whenever(stubActivityManager).getMemoryInfo(any()) + whenever( + appContext.mockInstance.getSystemService(Context.ACTIVITY_SERVICE) + ) doReturn stubActivityManager - @Test - fun `M collect memory W timeseries create() { total RAM available }`( - @StringForgery fakeSessionId: String, - @LongForgery(min = 1L) fakeTotalRamBytes: Long - ) { // When - val timeseries = createTimeseries(totalRamBytes = fakeTotalRamBytes, sessionId = fakeSessionId) + testedFeature.onInitialize(appContext.mockInstance) - // Then: both the CPU and memory pipelines are created. - check(timeseries is DefaultTimeseriesCollector) - assertThat(timeseries.pipelines).hasSize(2) + // Then + val timeseriesFactory = testedFeature.timeseriesCollectorFactory + check(timeseriesFactory is DefaultTimeseriesCollectorFactory) + assertThat(timeseriesFactory.getFieldValue, DefaultTimeseriesCollectorFactory>("dataWriter")) + .isSameAs(testedFeature.dataWriter) + assertThat( + timeseriesFactory.getFieldValue("insightsCollector") + ) + .isSameAs(testedFeature.insightsCollector) + assertThat( + timeseriesFactory + .getFieldValue("scheduledExecutorService") + ).isSameAs(testedFeature.vitalExecutorService) + assertThat(timeseriesFactory.getFieldValue("totalRamBytes")) + .isEqualTo(fakeTotalRamBytes) + assertThat( + timeseriesFactory.getFieldValue, DefaultTimeseriesCollectorFactory>("batteryInfoProvider") + ) + .isSameAs(testedFeature.batteryInfoProvider) + assertThat( + timeseriesFactory.getFieldValue, DefaultTimeseriesCollectorFactory>("displayInfoProvider") + ) + .isSameAs(testedFeature.displayInfoProvider) } @Test @@ -1916,18 +1924,6 @@ internal class RumFeatureTest { ) } - // Builds a timeseries collector for the given total device RAM (in bytes), bypassing the - // ActivityManager read so the skip/collect/log behavior can be exercised deterministically. - @OptIn(ExperimentalRumApi::class) - private fun createTimeseries(totalRamBytes: Long, sessionId: String): TimeseriesCollector = - testedFeature - .createTimeseriesCollectingFactory( - TimeseriesConfiguration.Builder().build(), - totalRamBytes, - testedFeature.configuration.insightsCollector - ) - .create(fakeApplicationId.toString(), sessionId, RumSessionType.USER, RumViewType.FOREGROUND) - private fun Forge.anApplicationExitInfoList( mustInclude: Int? = null ): List { diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumSessionTypeExtTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumSessionTypeExtTest.kt index f5283f6b4e..ac9174b1ac 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumSessionTypeExtTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumSessionTypeExtTest.kt @@ -11,8 +11,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent -import com.datadog.android.rum.model.TimeseriesCpuEvent -import com.datadog.android.rum.model.TimeseriesMemoryEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent.TimeseriesCpuEventSessionType +import com.datadog.android.rum.model.TimeseriesMemoryEvent.TimeseriesMemoryEventSessionType import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -75,14 +75,17 @@ internal class RumSessionTypeExtTest { @MethodSource("toTimeseriesMemorySessionTypeMappings") fun `M map session type W toTimeseriesMemorySessionType()`( input: RumSessionType, - expected: TimeseriesMemoryEvent.Type + expected: TimeseriesMemoryEventSessionType ) { assertThat(input.toTimeseriesMemorySessionType()).isEqualTo(expected) } @ParameterizedTest @MethodSource("toTimeseriesCpuSessionTypeMappings") - fun `M map session type W toTimeseriesCpuSessionType()`(input: RumSessionType, expected: TimeseriesCpuEvent.Type) { + fun `M map session type W toTimeseriesCpuSessionType()`( + input: RumSessionType, + expected: TimeseriesCpuEventSessionType + ) { assertThat(input.toTimeseriesCpuSessionType()).isEqualTo(expected) } @@ -144,14 +147,14 @@ internal class RumSessionTypeExtTest { @JvmStatic fun toTimeseriesMemorySessionTypeMappings(): List = listOf( - Arguments.of(RumSessionType.USER, TimeseriesMemoryEvent.Type.USER), - Arguments.of(RumSessionType.SYNTHETICS, TimeseriesMemoryEvent.Type.SYNTHETICS) + Arguments.of(RumSessionType.USER, TimeseriesMemoryEventSessionType.USER), + Arguments.of(RumSessionType.SYNTHETICS, TimeseriesMemoryEventSessionType.SYNTHETICS) ) @JvmStatic fun toTimeseriesCpuSessionTypeMappings(): List = listOf( - Arguments.of(RumSessionType.USER, TimeseriesCpuEvent.Type.USER), - Arguments.of(RumSessionType.SYNTHETICS, TimeseriesCpuEvent.Type.SYNTHETICS) + Arguments.of(RumSessionType.USER, TimeseriesCpuEventSessionType.USER), + Arguments.of(RumSessionType.SYNTHETICS, TimeseriesCpuEventSessionType.SYNTHETICS) ) } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/RumDataWriterTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/RumDataWriterTest.kt index e951353b12..8abd37a4ff 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/RumDataWriterTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/RumDataWriterTest.kt @@ -17,6 +17,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.utils.config.GlobalRumMonitorTestConfiguration import com.datadog.android.rum.utils.forge.Configurator @@ -46,6 +48,7 @@ import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doReturn import org.mockito.kotlin.doThrow +import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions @@ -204,6 +207,29 @@ internal class RumDataWriterTest { assertThat(captor.firstValue.eventType).isEqualTo("unknown") } + @Test + fun `M resolve timeseries event type W write() { generated timeseries events }`() { + // Given + val fakeEvents = listOf( + mock { on { type } doReturn "timeseries" }, + mock { on { type } doReturn "timeseries" } + ) + fakeEvents.forEach { whenever(mockSerializer.serialize(it)) doReturn fakeSerializedEvent } + + // When + fakeEvents.forEach { testedWriter.write(mockEventBatchWriter, it, fakeEventType) } + + // Then + val captor = argumentCaptor() + verify(mockEventBatchWriter, times(fakeEvents.size)).write( + any(), + anyOrNull(), + any(), + captor.capture() + ) + assertThat(captor.allValues.map { it.eventType }).containsOnly("timeseries") + } + @Test fun `M write data with event meta W write() {View Event}`( @Forgery fakeViewEvent: ViewEvent, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt index 04e838179d..d98586c7a8 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventMapperTest.kt @@ -12,6 +12,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -35,6 +37,7 @@ 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.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever @@ -283,6 +286,22 @@ internal class RumEventMapperTest { assertThat(mappedRumEvent).isSameAs(telemetryErrorEvent) } + @Test + fun `M return the original event W map() { timeseries events }`() { + // Given + val fakeEvents = listOf( + mock(), + mock() + ) + + // When + val mappedEvents = fakeEvents.map(testedRumEventMapper::map) + + // Then + verifyNoInteractions(mockInternalLogger) + assertThat(mappedEvents).containsExactlyElementsOf(fakeEvents) + } + @Test fun `M return the bundled event W map { TelemetryConfigurationEvent }`( @Forgery telemetryConfigurationEvent: TelemetryConfigurationEvent diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializerTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializerTest.kt index 5f645700a4..acca076c63 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializerTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/event/RumEventSerializerTest.kt @@ -14,6 +14,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.model.VitalAppLaunchEvent import com.datadog.android.rum.model.VitalOperationStepEvent @@ -92,8 +94,8 @@ internal class RumEventSerializerTest { hasField("type", event.session.type.name.lowercase(Locale.US)) } .hasField("view") { - hasField("id", event.view.id) - hasField("url", event.view.url) + hasNullableField("id", event.view?.id) + hasNullableField("url", event.view?.url) } .hasField("_dd") { hasField("format_version", 2L) @@ -209,8 +211,8 @@ internal class RumEventSerializerTest { hasField("type", event.session.type.name.lowercase(Locale.US)) } .hasField("view") { - hasField("id", event.view.id) - hasField("url", event.view.url) + hasNullableField("id", event.view?.id) + hasNullableField("url", event.view?.url) } .hasField("_dd") { hasField("format_version", 2L) @@ -401,8 +403,8 @@ internal class RumEventSerializerTest { hasField("type", event.session.type.name.lowercase(Locale.US)) } .hasField("view") { - hasField("id", event.view.id) - hasField("url", event.view.url) + hasNullableField("id", event.view?.id) + hasNullableField("url", event.view?.url) } .hasField("_dd") { hasField("format_version", 2L) @@ -488,8 +490,8 @@ internal class RumEventSerializerTest { hasField("type", event.session.type.name.lowercase(Locale.US)) } .hasField("view") { - hasField("id", event.view.id) - hasField("url", event.view.url) + hasNullableField("id", event.view?.id) + hasNullableField("url", event.view?.url) } .hasField("_dd") { hasField("format_version", 2L) @@ -667,7 +669,7 @@ internal class RumEventSerializerTest { } .hasNullableField("service", event.service) - event.view.let { + event.view?.let { assertThat(jsonObject).hasField("view") { val view = checkNotNull(event.view) hasField("id", view.id) @@ -1198,6 +1200,19 @@ internal class RumEventSerializerTest { assertThat(serialized).isEqualTo(fakeJsonObject.toString()) } + @Test + fun `M serialize generated event W serialize() { timeseries events }`() { + // Given + val fakeEvents = createTimeseriesEvents() + + // When + val serializedEvents = fakeEvents.map(testedSerializer::serialize) + + // Then + assertThat(serializedEvents.map { JsonParser.parseString(it).asJsonObject.get("type").asString }) + .containsOnly("timeseries") + } + @Test fun `M keep known custom attributes as is W serialize()`(forge: Forge) { val key = forge.anElementFrom(RumEventSerializer.knownAttributes) @@ -2176,6 +2191,50 @@ internal class RumEventSerializerTest { // region Internal + private fun createTimeseriesEvents(): List { + return listOf( + TimeseriesCpuEvent( + date = 0L, + application = TimeseriesCpuEvent.Application(id = "application-id"), + session = TimeseriesCpuEvent.TimeseriesCpuEventSession( + id = "session-id", + type = TimeseriesCpuEvent.TimeseriesCpuEventSessionType.USER + ), + dd = TimeseriesCpuEvent.Dd(), + timeseries = TimeseriesCpuEvent.Timeseries( + id = "timeseries-id", + start = 0L, + end = 0L, + data = TimeseriesCpuEvent.Data( + timestamps = emptyList(), + values = TimeseriesCpuEvent.Values(cpuUsage = emptyList()) + ) + ) + ), + TimeseriesMemoryEvent( + date = 0L, + application = TimeseriesMemoryEvent.Application(id = "application-id"), + session = TimeseriesMemoryEvent.TimeseriesMemoryEventSession( + id = "session-id", + type = TimeseriesMemoryEvent.TimeseriesMemoryEventSessionType.USER + ), + dd = TimeseriesMemoryEvent.Dd(), + timeseries = TimeseriesMemoryEvent.Timeseries( + id = "timeseries-id", + start = 0L, + end = 0L, + data = TimeseriesMemoryEvent.Data( + timestamps = emptyList(), + values = TimeseriesMemoryEvent.Values( + memoryFootprint = emptyList(), + memoryPercent = emptyList() + ) + ) + ) + ) + ) + } + private fun Forge.forgeRumEvent( attributes: MutableMap = mutableMapOf(), userAttributes: MutableMap = mutableMapOf() diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt index 71f32ae9a1..a89a7692f0 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeAttributePropagationTest.kt @@ -27,7 +27,7 @@ import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollect import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener import com.datadog.android.rum.internal.startup.RumAppStartupTelemetryReporter -import com.datadog.android.rum.internal.timeseries.TimeseriesCollector +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -136,12 +136,6 @@ internal class RumApplicationScopeAttributePropagationTest { @Mock lateinit var mockSessionSampler: Sampler - @Mock - lateinit var mockCollectorFactory: TimeseriesCollector.Factory - - @Mock - lateinit var mockCollector: TimeseriesCollector - @Forgery lateinit var fakeEventTime: Time @@ -201,7 +195,6 @@ internal class RumApplicationScopeAttributePropagationTest { fakeRumSessionType = forge.aNullable { aValueFrom(RumSessionType::class.java) } whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector testedScope = RumApplicationScope( applicationId = fakeApplicationId, sdkCore = rumMonitor.mockSdkCore, @@ -224,7 +217,7 @@ internal class RumApplicationScopeAttributePropagationTest { rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesCollectorFactory = mockCollectorFactory + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() ) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt index 8c48a62525..6e28a5a4b1 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt @@ -22,6 +22,7 @@ import com.datadog.android.rum.RumActionType import com.datadog.android.rum.RumSessionListener import com.datadog.android.rum.RumSessionType import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.domain.Time import com.datadog.android.rum.internal.domain.accessibility.AccessibilitySnapshotManager import com.datadog.android.rum.internal.domain.battery.BatteryInfo @@ -185,7 +186,7 @@ internal class RumApplicationScopeTest { whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector testedScope = RumApplicationScope( applicationId = fakeApplicationId, @@ -226,42 +227,17 @@ internal class RumApplicationScopeTest { } @Test - fun `M propagate timeseriesFactory to initial child session scope W handleEvent { startView }`( + fun `M propagate timeseriesFactory to every child session W handleEvent { startView, stop, startView }`( @StringForgery viewKey: String, @StringForgery viewName: String ) { - // When - delegating an interactive event triggers renewSession on the child session - testedScope.handleEvent( - RumRawEvent.StartView( - key = RumScopeKey.from(viewKey, viewName), - attributes = emptyMap(), - eventTime = fakeEventTime - ), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) - - // Then - the child session uses the same factory we gave to the application scope - verify(mockCollectorFactory).create(eq(fakeApplicationId), any(), any(), any()) - } - - @Test - fun `M propagate timeseriesFactory to a new child session W handleEvent { stop+startView }`( - @StringForgery viewKey: String, - @StringForgery viewName: String - ) { - // Given - first session that already used the factory - testedScope.handleEvent( - RumRawEvent.StartView( - key = RumScopeKey.from(viewKey, viewName), - attributes = emptyMap(), - eventTime = fakeEventTime - ), - fakeDatadogContext, - mockEventWriteScope, - mockWriter + // Given - the initial child session, renewed by an interactive event + val fakeStartViewEvent = RumRawEvent.StartView( + key = RumScopeKey.from(viewKey, viewName), + attributes = emptyMap(), + eventTime = fakeEventTime ) + testedScope.handleEvent(fakeStartViewEvent, fakeDatadogContext, mockEventWriteScope, mockWriter) testedScope.handleEvent( RumRawEvent.StopSession(fakeEventTime), fakeDatadogContext, @@ -269,20 +245,16 @@ internal class RumApplicationScopeTest { mockWriter ) - // When - a brand new session is started; the application scope must reuse the factory - testedScope.handleEvent( - RumRawEvent.StartView( - key = RumScopeKey.from(viewKey, viewName), - attributes = emptyMap(), - eventTime = fakeEventTime - ), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) + // When - a brand new child session scope is created by the application scope + testedScope.handleEvent(fakeStartViewEvent, fakeDatadogContext, mockEventWriteScope, mockWriter) - // Then - factory.create is invoked once per tracked session (initial + new) - verify(mockCollectorFactory, times(2)).create(eq(fakeApplicationId), any(), any(), any()) + // Then - both the initial and the new child session use the factory we gave the application scope + val rumContextCaptor = argumentCaptor() + verify(mockCollectorFactory, times(2)).create(any(), rumContextCaptor.capture(), any()) + assertThat(rumContextCaptor.allValues.map { it.applicationId }) + .containsOnly(fakeApplicationId) + assertThat(rumContextCaptor.firstValue.sessionId) + .isNotEqualTo(rumContextCaptor.secondValue.sessionId) } @Test diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExtTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExtTest.kt index 48026d185a..99b9bcbc7c 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExtTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumEventExtTest.kt @@ -17,6 +17,8 @@ import com.datadog.android.rum.model.ActionEvent import com.datadog.android.rum.model.ErrorEvent import com.datadog.android.rum.model.LongTaskEvent import com.datadog.android.rum.model.ResourceEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.model.ViewEvent import com.datadog.android.rum.utils.forge.Configurator import fr.xgouchet.elmyr.annotation.Forgery @@ -1039,6 +1041,86 @@ internal class RumEventExtTest { ) } + @ParameterizedTest + @EnumSource(NetworkInfo.Connectivity::class) + fun `M return connectivity W toTimeseriesCpuConnectivity()`( + connectivity: NetworkInfo.Connectivity, + @Forgery fakeNetworkInfo: NetworkInfo, + @StringForgery fakeCarrierName: String, + @StringForgery fakeCellularTechnology: String + ) { + // Given + val networkInfo = fakeNetworkInfo.copy( + connectivity = connectivity, + carrierName = fakeCarrierName, + cellularTechnology = fakeCellularTechnology + ) + + // When + val result = networkInfo.toTimeseriesCpuConnectivity() + + // Then + assertThat(result.status.name).isEqualTo(expectedStatusName(connectivity)) + assertThat(result.interfaces?.map { it.name }) + .isEqualTo(EXPECTED_INTERFACE_NAMES.getValue(connectivity)) + assertThat(result.cellular) + .isEqualTo(TimeseriesCpuEvent.Cellular(fakeCellularTechnology, fakeCarrierName)) + } + + @Test + fun `M return null cellular W toTimeseriesCpuConnectivity() {no carrier info}`( + @Forgery fakeNetworkInfo: NetworkInfo + ) { + // Given + val networkInfo = fakeNetworkInfo.copy(carrierName = null, cellularTechnology = null) + + // When + val result = networkInfo.toTimeseriesCpuConnectivity() + + // Then + assertThat(result.cellular).isNull() + } + + @ParameterizedTest + @EnumSource(NetworkInfo.Connectivity::class) + fun `M return connectivity W toTimeseriesMemoryConnectivity()`( + connectivity: NetworkInfo.Connectivity, + @Forgery fakeNetworkInfo: NetworkInfo, + @StringForgery fakeCarrierName: String, + @StringForgery fakeCellularTechnology: String + ) { + // Given + val networkInfo = fakeNetworkInfo.copy( + connectivity = connectivity, + carrierName = fakeCarrierName, + cellularTechnology = fakeCellularTechnology + ) + + // When + val result = networkInfo.toTimeseriesMemoryConnectivity() + + // Then + assertThat(result.status.name).isEqualTo(expectedStatusName(connectivity)) + assertThat(result.interfaces?.map { it.name }) + .isEqualTo(EXPECTED_INTERFACE_NAMES.getValue(connectivity)) + assertThat(result.cellular) + .isEqualTo(TimeseriesMemoryEvent.Cellular(fakeCellularTechnology, fakeCarrierName)) + } + + @Test + fun `M return null cellular W toTimeseriesMemoryConnectivity() {no carrier info}`( + @Forgery fakeNetworkInfo: NetworkInfo + ) { + // Given + val networkInfo = fakeNetworkInfo.copy(carrierName = null, cellularTechnology = null) + + // When + val result = networkInfo.toTimeseriesMemoryConnectivity() + + // Then + assertThat(result.cellular).isNull() + } + // endregion // region device type conversion @@ -1103,5 +1185,58 @@ internal class RumEventExtTest { assertThat(schemaDeviceType.name).isEqualTo(deviceType.name) } + @ParameterizedTest + @EnumSource(DeviceType::class) + fun `M return schema device type W toTimeseriesCpuSchemaType()`( + deviceType: DeviceType + ) { + // When + val schemaDeviceType = deviceType.toTimeseriesCpuSchemaType() + + // Then + assertThat(schemaDeviceType.name).isEqualTo(deviceType.name) + } + + @ParameterizedTest + @EnumSource(DeviceType::class) + fun `M return schema device type W toTimeseriesMemorySchemaType()`( + deviceType: DeviceType + ) { + // When + val schemaDeviceType = deviceType.toTimeseriesMemorySchemaType() + + // Then + assertThat(schemaDeviceType.name).isEqualTo(deviceType.name) + } + // endregion + + companion object { + + // Interface enums are generated per event type but share their names, so a single + // name-based table covers both timeseries schemas. getValue() fails loudly if a new + // Connectivity value is added without updating the mapping. + private val EXPECTED_INTERFACE_NAMES = mapOf( + NetworkInfo.Connectivity.NETWORK_NOT_CONNECTED to emptyList(), + NetworkInfo.Connectivity.NETWORK_ETHERNET to listOf("ETHERNET"), + NetworkInfo.Connectivity.NETWORK_WIFI to listOf("WIFI"), + NetworkInfo.Connectivity.NETWORK_WIMAX to listOf("WIMAX"), + NetworkInfo.Connectivity.NETWORK_BLUETOOTH to listOf("BLUETOOTH"), + NetworkInfo.Connectivity.NETWORK_2G to listOf("CELLULAR"), + NetworkInfo.Connectivity.NETWORK_3G to listOf("CELLULAR"), + NetworkInfo.Connectivity.NETWORK_4G to listOf("CELLULAR"), + NetworkInfo.Connectivity.NETWORK_5G to listOf("CELLULAR"), + NetworkInfo.Connectivity.NETWORK_MOBILE_OTHER to listOf("CELLULAR"), + NetworkInfo.Connectivity.NETWORK_CELLULAR to listOf("CELLULAR"), + NetworkInfo.Connectivity.NETWORK_OTHER to listOf("OTHER") + ) + + private fun expectedStatusName(connectivity: NetworkInfo.Connectivity): String { + return if (connectivity == NetworkInfo.Connectivity.NETWORK_NOT_CONNECTED) { + "NOT_CONNECTED" + } else { + "CONNECTED" + } + } + } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt index 6c5eea380e..20f4e310c4 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeAttributePropagationTest.kt @@ -26,7 +26,6 @@ import com.datadog.android.rum.internal.domain.display.DisplayInfo import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector import com.datadog.android.rum.internal.metric.SessionMetricDispatcher import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener -import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.vitals.VitalMonitor import com.datadog.android.rum.metric.interactiontonextview.LastInteractionIdentifier import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier @@ -129,12 +128,6 @@ internal class RumSessionScopeAttributePropagationTest { @Mock lateinit var mockSessionSampler: Sampler - @Mock - lateinit var mockCollectorFactory: TimeseriesCollector.Factory - - @Mock - lateinit var mockCollector: TimeseriesCollector - lateinit var fakeParentAttributes: Map @Forgery @@ -171,7 +164,6 @@ internal class RumSessionScopeAttributePropagationTest { fakeRumSessionType = forge.aNullable { aValueFrom(RumSessionType::class.java) } whenever(mockSessionSampler.getSampleRate()).thenReturn(fakeSampleRate) whenever(mockSessionSampler.sample(any())).thenReturn(true) - whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector testedScope = RumSessionScope( parentScope = mockParentScope, sdkCore = mockSdkCore, @@ -197,8 +189,7 @@ internal class RumSessionScopeAttributePropagationTest { displayInfoProvider = mockDisplayInfoProvider, rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, - heatmapIdentifierRegistry = null, - timeseriesCollectorFactory = mockCollectorFactory + heatmapIdentifierRegistry = null ) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt index d167924e1a..29486acddd 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScopeTest.kt @@ -50,7 +50,6 @@ import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.BoolForgery import fr.xgouchet.elmyr.annotation.FloatForgery import fr.xgouchet.elmyr.annotation.Forgery -import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat @@ -60,6 +59,7 @@ 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.Arguments import org.junit.jupiter.params.provider.MethodSource import org.mockito.Mock import org.mockito.Mockito @@ -67,11 +67,9 @@ import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor -import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq -import org.mockito.kotlin.inOrder import org.mockito.kotlin.isA import org.mockito.kotlin.mock import org.mockito.kotlin.never @@ -230,7 +228,7 @@ internal class RumSessionScopeTest { whenever(mockDisplayInfoProvider.getState()) doReturn fakeDisplayInfo whenever(mockSessionSampler.sample(any())).thenReturn(true) whenever(mockSessionSampler.getSampleRate()).thenReturn(100f) - whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn mockCollector + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn mockCollector fakeParentAttributes = forge.exhaustiveAttributes() whenever(mockParentScope.getCustomAttributes()) doReturn fakeParentAttributes @@ -1855,10 +1853,11 @@ internal class RumSessionScopeTest { // region Timeseries @Test - fun `M start timeseries via factory W renewSession { keepSession = true }`(forge: Forge) { + fun `M start timeseries with session context W renewSession { keepSession = true, no active view }`( + forge: Forge + ) { // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = null) - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) // When testedScope.handleEvent( @@ -1869,171 +1868,78 @@ internal class RumSessionScopeTest { ) // Then - verify(mockCollectorFactory).create( - eq(fakeParentContext.applicationId), - eq(testedScope.sessionId), - eq(fakeRumSessionType ?: RumSessionType.USER), - any() - ) + val rumContextCaptor = argumentCaptor() + verify(mockCollectorFactory).create(any(), rumContextCaptor.capture(), any()) + assertThat(rumContextCaptor.firstValue).isEqualTo(testedScope.getRumContext()) verify(mockCollector).onSessionStart() } @Test - fun `M pass USER session type to factory W renewSession { no synthetics, no override }`(forge: Forge) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = null) - fakeRumSessionType = null - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + fun `M pass session custom attributes provider to factory W renewSession`(forge: Forge) { + // Given — the parent scope holds fakeParentAttributes (stubbed in set up) + initializeTestedScope(collectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - // Then - verify(mockCollectorFactory).create( - eq(fakeParentContext.applicationId), - eq(testedScope.sessionId), - eq(RumSessionType.USER), - any() - ) + // Then — the provider handed to the factory resolves to the session's current custom attributes + val customAttributesCaptor = argumentCaptor<() -> Map>() + verify(mockCollectorFactory).create(any(), any(), customAttributesCaptor.capture()) + assertThat(customAttributesCaptor.firstValue.invoke()) + .isEqualTo(testedScope.getCustomAttributes()) + .isEqualTo(fakeParentAttributes) } @Test - fun `M pass SYNTHETICS session type to factory W renewSession { synthetics IDs in context, no override }`( - forge: Forge, - @StringForgery(regex = "[a-z]{8}") fakeTestId: String, - @StringForgery(regex = "[a-z]{8}") fakeResultId: String - ) { + fun `M pass active view context to factory W renewSession { foreground view active }`(forge: Forge) { // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = fakeResultId) - fakeRumSessionType = null - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + val mockViewScope = mock() + val fakeViewContext = forge.getForgery().copy(viewType = RumViewType.FOREGROUND) + whenever(mockChildScope.activeView) doReturn mockViewScope + whenever(mockViewScope.getRumContext()) doReturn fakeViewContext + initializeTestedScope(collectorFactory = mockCollectorFactory) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - // Then - verify(mockCollectorFactory).create( - eq(fakeParentContext.applicationId), - eq(testedScope.sessionId), - eq(RumSessionType.SYNTHETICS), - any() - ) + // Then — the view context, not the session scope one (which has viewType NONE) + val rumContextCaptor = argumentCaptor() + verify(mockCollectorFactory).create(any(), rumContextCaptor.capture(), any()) + assertThat(rumContextCaptor.firstValue).isEqualTo(fakeViewContext) + assertThat(rumContextCaptor.firstValue).isNotEqualTo(testedScope.getRumContext()) } - @Test - fun `M pass override session type to factory W renewSession { synthetics IDs in context, override set }`( - forge: Forge, - @StringForgery(regex = "[a-z]{8}") fakeTestId: String, - @StringForgery(regex = "[a-z]{8}") fakeResultId: String - ) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = fakeResultId) - val expectedSessionType = forge.aValueFrom(RumSessionType::class.java) - fakeRumSessionType = expectedSessionType - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockCollectorFactory).create( - eq(fakeParentContext.applicationId), - eq(testedScope.sessionId), - eq(expectedSessionType), - any() - ) - } - - @Test - fun `M pass override session type to factory W renewSession { no synthetics, override set }`( + @ParameterizedTest + @MethodSource("sessionTypeResolutions") + fun `M pass resolved session type to factory W renewSession`( + fakeSyntheticsTestId: String?, + fakeSyntheticsResultId: String?, + fakeSessionTypeOverride: RumSessionType?, + expectedSessionType: RumSessionType, forge: Forge ) { // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = null) - val expectedSessionType = forge.aValueFrom(RumSessionType::class.java) - fakeRumSessionType = expectedSessionType - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockCollectorFactory).create(any(), any(), eq(expectedSessionType), any()) - } - - @Test - fun `M pass USER session type to factory W renewSession { testId null, no override }`( - forge: Forge, - @StringForgery(regex = "[a-z]{8}") fakeResultId: String - ) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = null, syntheticsResultId = fakeResultId) - fakeRumSessionType = null - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) - } - - @Test - fun `M pass USER session type to factory W renewSession { resultId null, no override }`( - forge: Forge, - @StringForgery(regex = "[a-z]{8}") fakeTestId: String - ) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = null) - fakeRumSessionType = null - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) - } - - @Test - fun `M pass USER session type to factory W renewSession { testId blank, no override }`( - forge: Forge, - @StringForgery(regex = "[a-z]{8}") fakeResultId: String - ) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = " ", syntheticsResultId = fakeResultId) - fakeRumSessionType = null - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) - } - - @Test - fun `M pass USER session type to factory W renewSession { resultId blank, no override }`( - forge: Forge, - @StringForgery(regex = "[a-z]{8}") fakeTestId: String - ) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = " ") - fakeRumSessionType = null - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + fakeParentContext = fakeParentContext.copy( + syntheticsTestId = fakeSyntheticsTestId, + syntheticsResultId = fakeSyntheticsResultId + ) + initializeTestedScope( + collectorFactory = mockCollectorFactory, + rumSessionTypeOverride = fakeSessionTypeOverride + ) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockCollectorFactory).create(any(), any(), eq(RumSessionType.USER), any()) + verify(mockCollectorFactory).create(eq(expectedSessionType), any(), any()) } @Test fun `M not start timeseries W renewSession { keepSession = false }`(forge: Forge) { // Given whenever(mockSessionSampler.sample(any())).thenReturn(false) - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) // When testedScope.handleEvent( @@ -2044,40 +1950,39 @@ internal class RumSessionScopeTest { ) // Then - verify(mockCollectorFactory, never()).create(any(), any(), any(), any()) + verify(mockCollectorFactory, never()).create(any(), any(), any()) verify(mockCollector, never()).onSessionStart() } @Test - fun `M stop previous timeseries W renewSession { another tracked session }`(forge: Forge) { + fun `M stop previous and feed fresh timeseries W renewSession { another tracked session }`(forge: Forge) { // Given - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - testedScope.handleEvent( - forge.startViewEvent(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) + val mockViewScope = mock() + val fakeViewContext = forge.getForgery().copy(viewType = RumViewType.FOREGROUND) + whenever(mockChildScope.activeView) doReturn mockViewScope + whenever(mockViewScope.getRumContext()) doReturn fakeViewContext + initializeTestedScope(collectorFactory = mockCollectorFactory) + testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) + val firstTimeseries = mockCollector + val secondCollector: TimeseriesCollector = mock() + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector // When — second session via inactivity expiration advanceTimeByMs(TEST_INACTIVITY_MS) - testedScope.handleEvent( - forge.startViewEvent(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) + testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - // Then - verify(mockCollector).onSessionStop() - verify(mockCollectorFactory, times(2)).create(any(), any(), any(), any()) - verify(mockCollector, times(2)).onSessionStart() + // Then — one timeseries per tracked session, updates go to the live one only + verify(mockCollectorFactory, times(2)).create(any(), any(), any()) + verify(firstTimeseries).onSessionStop() + verify(firstTimeseries, times(1)).onRumContextUpdate(fakeViewContext) + verify(secondCollector).onSessionStart() + verify(secondCollector).onRumContextUpdate(fakeViewContext) } @Test fun `M stop timeseries W handleEvent { session expires without renewal }`(forge: Forge) { // Given - initializeTestedScope(backgroundTrackingEnabled = false, timeseriesCollectorFactory = mockCollectorFactory) + initializeTestedScope(backgroundTrackingEnabled = false, collectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2097,7 +2002,7 @@ internal class RumSessionScopeTest { @Test fun `M stop timeseries W handleEvent { StopSession }`(forge: Forge) { // Given - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2118,122 +2023,54 @@ internal class RumSessionScopeTest { } @Test - fun `M not interact with timeseries W renewSession { default NoOp factory }`(forge: Forge) { - // When - val result = testedScope.handleEvent( - forge.startViewEvent(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) - - // Then - assertThat(result).isSameAs(testedScope) - verifyNoInteractions(mockCollector, mockCollectorFactory) - } - - @Test - fun `M notify timeseries of view type W handleEvent`(forge: Forge) { - // Given - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - testedScope.handleEvent( - forge.startViewEvent(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) + fun `M pass session context W onRumContextUpdate() { no active view }`(forge: Forge) { + // Given — activeView is null by default (mockChildScope.activeView not stubbed) + initializeTestedScope(collectorFactory = mockCollectorFactory) + testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // When - testedScope.handleEvent( - forge.addErrorEvent(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) + testedScope.handleEvent(forge.addErrorEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - // Then — called once per handleEvent invocation - verify(mockCollector, times(2)).onViewTypeUpdate(any()) + // Then — the session scope context, once per handled event + val rumContextCaptor = argumentCaptor() + verify(mockCollector, times(2)).onRumContextUpdate(rumContextCaptor.capture()) + assertThat(rumContextCaptor.allValues).containsOnly(testedScope.getRumContext()) } @Test - fun `M pass foreground view type W onViewTypeUpdate { first StartView creates view }`(forge: Forge) { - // Given + fun `M pass active view context W onRumContextUpdate() { StartView creates a foreground view }`(forge: Forge) { + // Given — a real view manager child scope, so the context comes from an actual RumViewScope initializeTestedScope( withMockChildScope = false, - timeseriesCollectorFactory = mockCollectorFactory + collectorFactory = mockCollectorFactory ) + val fakeStartViewEvent = forge.startViewEvent() // When testedScope.handleEvent( - forge.startViewEvent(), + fakeStartViewEvent, fakeDatadogContext, mockEventWriteScope, mockWriter ) // Then - verify(mockCollector).onViewTypeUpdate(RumViewType.FOREGROUND) - verify(mockCollector, never()).onViewTypeUpdate(RumViewType.NONE) + val rumContextCaptor = argumentCaptor() + verify(mockCollector).onRumContextUpdate(rumContextCaptor.capture()) + assertThat(rumContextCaptor.firstValue.viewType).isEqualTo(RumViewType.FOREGROUND) + assertThat(rumContextCaptor.firstValue.viewName).isEqualTo(fakeStartViewEvent.key.name) + assertThat(rumContextCaptor.firstValue.viewId).isNotNull + assertThat(rumContextCaptor.firstValue.sessionId).isEqualTo(testedScope.sessionId) } @Test - fun `M pass NONE W onViewTypeUpdate { no active view }`(forge: Forge) { - // Given — activeView is null by default (mockChildScope.activeView not stubbed) - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // When - testedScope.handleEvent(forge.addErrorEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockCollector, times(2)).onViewTypeUpdate(RumViewType.NONE) - } - - @Test - fun `M pass active view type W onViewTypeUpdate { foreground view active }`(forge: Forge) { - // Given - val mockViewScope = mock() - val fakeRumContext = forge.getForgery().copy(viewType = RumViewType.FOREGROUND) - whenever(mockChildScope.activeView) doReturn mockViewScope - whenever(mockViewScope.getRumContext()) doReturn fakeRumContext - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // When - testedScope.handleEvent(forge.addErrorEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then — at least the last call carries FOREGROUND - verify(mockCollector, atLeastOnce()).onViewTypeUpdate(RumViewType.FOREGROUND) - } - - @Test - fun `M pass view type to fresh timeseries W renewSession { session renewed }`(forge: Forge) { - // Given — active foreground view throughout - val mockViewScope = mock() - val fakeRumContext = forge.getForgery().copy(viewType = RumViewType.FOREGROUND) - whenever(mockChildScope.activeView) doReturn mockViewScope - whenever(mockViewScope.getRumContext()) doReturn fakeRumContext - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // When — expire session and start a new one - advanceTimeByMs(TEST_INACTIVITY_MS) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then — second timeseries (same factory mock) also receives FOREGROUND right after start() - val inOrder = inOrder(mockCollector) - inOrder.verify(mockCollector, times(2)).onSessionStart() - inOrder.verify(mockCollector).onViewTypeUpdate(RumViewType.FOREGROUND) - } - - @Test - fun `M stop previous timeseries W renewSession { ResetSession renews tracked session }`(forge: Forge) { + fun `M stop previous timeseries W handleEvent { ResetSession }`(forge: Forge) { // Given - initializeTestedScope(timeseriesCollectorFactory = mockCollectorFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - val firstCollector = mockCollector + val firstTimeseries = mockCollector val secondCollector: TimeseriesCollector = mock() - whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn secondCollector + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector // When testedScope.handleEvent( @@ -2244,33 +2081,15 @@ internal class RumSessionScopeTest { ) // Then - verify(firstCollector).onSessionStart() - verify(firstCollector).onSessionStop() + verify(firstTimeseries).onSessionStop() verify(secondCollector).onSessionStart() } @Test - fun `M stop previous timeseries W renewSession { expired session then new interaction }`(forge: Forge) { + fun `M not create timeseries W handleEvent { StopSession, no tracked session }`() { // Given - initializeTestedScope(backgroundTrackingEnabled = false, timeseriesCollectorFactory = mockCollectorFactory) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - val firstCollector = mockCollector - val secondCollector: TimeseriesCollector = mock() - whenever(mockCollectorFactory.create(any(), any(), any(), any())) doReturn secondCollector - advanceTimeByMs(TEST_INACTIVITY_MS) - testedScope.handleEvent(mock(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // When - testedScope.handleEvent(forge.startActionEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(firstCollector).onSessionStart() - verify(firstCollector).onSessionStop() - verify(secondCollector).onSessionStart() - } + initializeTestedScope(collectorFactory = mockCollectorFactory) - @Test - fun `M not stop timeseries W handleEvent { StopSession, no tracked session }`() { // When testedScope.handleEvent( RumRawEvent.StopSession(eventTime = currentFakeTime()), @@ -2280,6 +2099,7 @@ internal class RumSessionScopeTest { ) // Then + verify(mockCollectorFactory, never()).create(any(), any(), any()) verifyNoInteractions(mockCollector) } @@ -2302,7 +2122,8 @@ internal class RumSessionScopeTest { sessionSampler: Sampler = mockSessionSampler, withMockChildScope: Boolean = true, backgroundTrackingEnabled: Boolean? = null, - timeseriesCollectorFactory: TimeseriesCollector.Factory = NoOpTimeseriesCollectorFactory() + collectorFactory: TimeseriesCollector.Factory = NoOpTimeseriesCollectorFactory(), + rumSessionTypeOverride: RumSessionType? = fakeRumSessionType ) { testedScope = RumSessionScope( parentScope = mockParentScope, @@ -2323,14 +2144,14 @@ internal class RumSessionScopeTest { slowFramesListener = mockSlowFramesListener, sessionInactivityNanos = TEST_INACTIVITY_NS, sessionMaxDurationNanos = TEST_MAX_DURATION_NS, - rumSessionTypeOverride = fakeRumSessionType, + rumSessionTypeOverride = rumSessionTypeOverride, accessibilitySnapshotManager = mockAccessibilitySnapshotManager, batteryInfoProvider = mockBatteryInfoProvider, displayInfoProvider = mockDisplayInfoProvider, rumSessionScopeStartupManagerFactory = { mockRumSessionScopeStartupManager }, insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesCollectorFactory = timeseriesCollectorFactory + timeseriesCollectorFactory = collectorFactory ) if (withMockChildScope) { @@ -2349,6 +2170,27 @@ internal class RumSessionScopeTest { private val TEST_INACTIVITY_NS = TimeUnit.MILLISECONDS.toNanos(TEST_INACTIVITY_MS) private val TEST_MAX_DURATION_NS = TimeUnit.MILLISECONDS.toNanos(TEST_MAX_DURATION_MS) + private const val FAKE_SYNTHETICS_TEST_ID = "fake-synthetics-test-id" + private const val FAKE_SYNTHETICS_RESULT_ID = "fake-synthetics-result-id" + + // syntheticsTestId, syntheticsResultId, rumSessionTypeOverride, expected session type + @JvmStatic + fun sessionTypeResolutions(): List = listOf( + Arguments.of(null, null, null, RumSessionType.USER), + Arguments.of(FAKE_SYNTHETICS_TEST_ID, FAKE_SYNTHETICS_RESULT_ID, null, RumSessionType.SYNTHETICS), + Arguments.of(null, FAKE_SYNTHETICS_RESULT_ID, null, RumSessionType.USER), + Arguments.of(FAKE_SYNTHETICS_TEST_ID, null, null, RumSessionType.USER), + Arguments.of(" ", FAKE_SYNTHETICS_RESULT_ID, null, RumSessionType.USER), + Arguments.of(FAKE_SYNTHETICS_TEST_ID, " ", null, RumSessionType.USER), + Arguments.of( + FAKE_SYNTHETICS_TEST_ID, + FAKE_SYNTHETICS_RESULT_ID, + RumSessionType.USER, + RumSessionType.USER + ), + Arguments.of(null, null, RumSessionType.SYNTHETICS, RumSessionType.SYNTHETICS) + ) + @JvmStatic fun testScenarios(): List { val forge = Forge().apply { diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt index f89602f30c..411b721980 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt @@ -10603,8 +10603,8 @@ internal class RumViewScopeTest { assertThat(profilerEvent.rumContext.applicationId).isEqualTo(writtenVital.application.id) assertThat(profilerEvent.rumContext.sessionId).isEqualTo(writtenVital.session.id) - assertThat(profilerEvent.rumContext.viewId).isEqualTo(writtenVital.view.id) - assertThat(profilerEvent.rumContext.viewName).isEqualTo(writtenVital.view.name) + assertThat(profilerEvent.rumContext.viewId).isEqualTo(writtenVital.view?.id) + assertThat(profilerEvent.rumContext.viewName).isEqualTo(writtenVital.view?.name) } @Test diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/BufferTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/BufferTest.kt index a480423d92..fc390c59b1 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/BufferTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/BufferTest.kt @@ -69,7 +69,7 @@ internal class BufferTest { } @Test - fun `M return null W drain() { buffer is empty }`(@IntForgery(min = 1, max = 256) fakeSize: Int) { + fun `M return empty list W drain() { buffer is empty }`(@IntForgery(min = 1, max = 256) fakeSize: Int) { // Given val testedBuffer = Buffer(fakeSize) @@ -100,19 +100,20 @@ internal class BufferTest { } @Test - fun `M return immutable snapshot W drain() { caller cannot affect internal state }`( - @IntForgery(min = 1, max = 16) fakeSize: Int, + fun `M return a detached copy W drain() { buffer is reused afterwards }`( + @IntForgery(min = 2, max = 16) fakeSize: Int, forge: Forge ) { // Given val testedBuffer = Buffer(fakeSize) - repeat(fakeSize) { testedBuffer.add(forge.getForgery>()) } + val fakePoints = (0 until fakeSize).map { forge.getForgery>() } + fakePoints.forEach { testedBuffer.add(it) } val drained = testedBuffer.drain() - // When - the buffer should be cleared after drain + // When testedBuffer.add(forge.getForgery>()) - // Then - drained list size unchanged regardless of further mutations - assertThat(drained).hasSize(fakeSize) + // Then + assertThat(drained).containsExactlyElementsOf(fakePoints) } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt index 208c84b1bd..f46b637ec8 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt @@ -9,33 +9,39 @@ package com.datadog.android.rum.internal.timeseries import com.datadog.android.api.InternalLogger import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter +import com.datadog.android.internal.time.TimeProvider +import com.datadog.android.rum.ExperimentalRumApi import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.domain.scope.RumViewType -import com.datadog.android.rum.internal.timeseries.provider.DataPointsReader -import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector +import com.datadog.android.rum.internal.timeseries.factory.CpuEventFactory +import com.datadog.android.rum.internal.timeseries.factory.MemoryEventFactory +import com.datadog.android.rum.timeseries.TimeseriesConfiguration +import com.datadog.android.rum.timeseries.TimeseriesType import com.datadog.android.rum.utils.forge.Configurator -import fr.xgouchet.elmyr.annotation.StringForgery +import com.datadog.android.utils.verifyLog +import com.datadog.tools.unit.getFieldValue +import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.annotation.Forgery +import fr.xgouchet.elmyr.annotation.LongForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat +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.EnumSource 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.doReturn -import org.mockito.kotlin.eq -import org.mockito.kotlin.mock -import org.mockito.kotlin.never -import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.mockito.quality.Strictness import java.util.concurrent.ScheduledExecutorService -import java.util.concurrent.TimeUnit @Extensions( ExtendWith(MockitoExtension::class), @@ -43,6 +49,7 @@ import java.util.concurrent.TimeUnit ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) +@OptIn(ExperimentalRumApi::class) internal class DefaultTimeseriesCollectorFactoryTest { @Mock @@ -51,102 +58,230 @@ internal class DefaultTimeseriesCollectorFactoryTest { @Mock lateinit var mockInternalLogger: InternalLogger + @Mock + lateinit var mockTimeProvider: TimeProvider + @Mock lateinit var mockWriter: DataWriter @Mock lateinit var mockExecutor: ScheduledExecutorService + @Mock + lateinit var mockInsightsCollector: InsightsCollector + + @Mock + lateinit var mockBatteryInfoProvider: InfoProvider + + @Mock + lateinit var mockDisplayInfoProvider: InfoProvider + + @Forgery + lateinit var fakeRumContext: RumContext + + lateinit var fakeSessionType: RumSessionType + + private val fakeCustomAttributes: () -> Map = { emptyMap() } + + @BeforeEach + fun `set up`(forge: Forge) { + whenever(mockSdkCore.internalLogger) doReturn mockInternalLogger + whenever(mockSdkCore.timeProvider) doReturn mockTimeProvider + + fakeSessionType = forge.aValueFrom(RumSessionType::class.java) + } + + private fun createFactory( + totalRamBytes: Long, + configuration: TimeseriesConfiguration = TimeseriesConfiguration.Builder().build() + ) = DefaultTimeseriesCollectorFactory( + sdkCore = mockSdkCore, + configuration = configuration, + scheduledExecutorService = mockExecutor, + insightsCollector = mockInsightsCollector, + totalRamBytes = totalRamBytes, + dataWriter = mockWriter, + batteryInfoProvider = mockBatteryInfoProvider, + displayInfoProvider = mockDisplayInfoProvider + ) + + @Test + fun `M build cpu and memory pipelines W create() { totalRamBytes greater than zero }`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long + ) { + // Given + val testedFactory = createFactory(fakeTotalRamBytes) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) + + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).hasSize(2) + } + @Test - fun `M build DefaultTimeseriesCollector with provided pipelines W create()`( - @StringForgery fakeSessionId: String, - @StringForgery fakeApplicationId: String + fun `M use default sampling settings W create()`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long ) { // Given - val fakeSessionType = RumSessionType.USER - val pipelineA = mockPipeline() - val pipelineB = mockPipeline() - val provider: (String, String, RumSessionType) -> List> = - mock<(String, String, RumSessionType) -> List>>().apply { - whenever(this(fakeSessionId, fakeApplicationId, fakeSessionType)) - .thenReturn(listOf(pipelineA, pipelineB)) + val testedFactory = createFactory(fakeTotalRamBytes) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) + + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines.map { it.intervalMs }) + .containsOnly(TimeseriesConfiguration.DEFAULT_INTERVAL_MS) + assertThat( + timeseries.pipelines.map { pipeline -> + pipeline.getFieldValue, Pipeline<*>>("buffer") + .getFieldValue>("size") } - val testedFactory = DefaultTimeseriesCollectorFactory( - internalLogger = mockInternalLogger, - scheduledExecutorService = mockExecutor, - pipelinesProvider = provider - ) + ).containsOnly(TimeseriesConfiguration.DEFAULT_BUFFER_SIZE) + } + + @Test + fun `M build only cpu pipeline W create() { totalRamBytes is zero }`() { + // Given + val testedFactory = createFactory(0L) // When - val timeseries = testedFactory.create( - fakeSessionId, - fakeApplicationId, - fakeSessionType, - RumViewType.FOREGROUND + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) + + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).hasSize(1) + mockInternalLogger.verifyLog( + InternalLogger.Level.WARN, + InternalLogger.Target.USER, + DefaultTimeseriesCollectorFactory.MEMORY_TIMESERIES_DISABLED_MESSAGE, + onlyOnce = true ) + } + + @Test + fun `M build only cpu pipeline W create() { configuration collects only cpu }`() { + // Given + val fakeConfiguration = TimeseriesConfiguration.Builder() + .collectOnly(TimeseriesType.CPU) + .build() + val testedFactory = createFactory(0L, fakeConfiguration) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) // Then - verify(provider).invoke(fakeSessionId, fakeApplicationId, fakeSessionType) - assertThat(timeseries.scheduledExecutorService).isSameAs(mockExecutor) - assertThat(timeseries.pipelines).containsExactly(pipelineA, pipelineB) + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).hasSize(1) + val eventFactory = timeseries.pipelines.single() + .getFieldValue>("eventFactory") + assertThat(eventFactory).isInstanceOf(CpuEventFactory::class.java) + verifyNoInteractions(mockInternalLogger) } - @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["FOREGROUND", "APPLICATION_LAUNCH"]) - fun `M seed collector with provided view type W create() { foreground view }`( - fakeViewType: RumViewType, - @StringForgery fakeSessionId: String, - @StringForgery fakeApplicationId: String + @Test + fun `M build only memory pipeline W create() { configuration collects only memory }`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long ) { // Given - val timeseries = createCollectorSeededWith(fakeViewType, fakeSessionId, fakeApplicationId) + val fakeConfiguration = TimeseriesConfiguration.Builder() + .collectOnly(TimeseriesType.MEMORY) + .build() + val testedFactory = createFactory(fakeTotalRamBytes, fakeConfiguration) // When - timeseries.onSessionStart() + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) - // Then — the seeded view type is a foreground one, so sampling starts right away - verify(mockExecutor).schedule(any(), eq(FAKE_INTERVAL_MS), eq(TimeUnit.MILLISECONDS)) + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).hasSize(1) + val eventFactory = timeseries.pipelines.single() + .getFieldValue>("eventFactory") + assertThat(eventFactory).isInstanceOf(MemoryEventFactory::class.java) } - @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) - fun `M seed collector with provided view type W create() { non-foreground view }`( - fakeViewType: RumViewType, - @StringForgery fakeSessionId: String, - @StringForgery fakeApplicationId: String + @Test + fun `M build no pipelines W create() { configuration collects no types }`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long ) { // Given - val timeseries = createCollectorSeededWith(fakeViewType, fakeSessionId, fakeApplicationId) + val fakeConfiguration = TimeseriesConfiguration.Builder() + .collectOnly(*emptyArray()) + .build() + val testedFactory = createFactory(fakeTotalRamBytes, fakeConfiguration) // When - timeseries.onSessionStart() + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) - // Then — a session starting outside the foreground must not schedule any sampling - verify(mockExecutor, never()).schedule(any(), any(), any()) + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).isEmpty() } - private fun createCollectorSeededWith( - viewType: RumViewType, - sessionId: String, - applicationId: String - ): TimeseriesCollector { - val testedFactory = DefaultTimeseriesCollectorFactory( - internalLogger = mockInternalLogger, - scheduledExecutorService = mockExecutor, - pipelinesProvider = { _, _, _ -> listOf(mockPipeline()) } - ) - return testedFactory.create(sessionId, applicationId, RumSessionType.USER, viewType) - } + @Test + fun `M propagate executor and rum context to the collector W create()`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long + ) { + // Given + val testedFactory = createFactory(fakeTotalRamBytes) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) - private fun mockPipeline(): Pipeline<*> { - val reader = mock> { - on { intervalMs } doReturn FAKE_INTERVAL_MS - } - val serializer = mock>() - return Pipeline(mockSdkCore, reader, Buffer(1), serializer, mockWriter, mockInternalLogger) + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.scheduledExecutorService).isSameAs(mockExecutor) + assertThat( + timeseries.getFieldValue("rumContext") + ).isSameAs(fakeRumContext) } - private companion object { - const val FAKE_INTERVAL_MS = 1_000L + @Test + fun `M propagate session type, info providers and customAttributes to both factories W create()`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long + ) { + // Given + val testedFactory = createFactory(fakeTotalRamBytes) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) + + // Then + check(timeseries is DefaultTimeseriesCollector) + val cpuEventFactory = timeseries.pipelines[0] + .getFieldValue>("eventFactory") + val memoryEventFactory = timeseries.pipelines[1] + .getFieldValue>("eventFactory") + + assertThat( + cpuEventFactory.getFieldValue("sessionType") + ).isEqualTo(fakeSessionType) + assertThat( + cpuEventFactory.getFieldValue, CpuEventFactory>("batteryInfoProvider") + ).isSameAs(mockBatteryInfoProvider) + assertThat( + cpuEventFactory.getFieldValue, CpuEventFactory>("displayInfoProvider") + ).isSameAs(mockDisplayInfoProvider) + assertThat( + timeseries.pipelines[0].getFieldValue>("customAttributes") + ).isSameAs(fakeCustomAttributes) + + assertThat( + memoryEventFactory.getFieldValue("sessionType") + ).isEqualTo(fakeSessionType) + assertThat( + memoryEventFactory.getFieldValue("totalRamBytes") + ).isEqualTo(fakeTotalRamBytes) + assertThat( + memoryEventFactory.getFieldValue, MemoryEventFactory>("batteryInfoProvider") + ).isSameAs(mockBatteryInfoProvider) + assertThat( + memoryEventFactory.getFieldValue, MemoryEventFactory>("displayInfoProvider") + ).isSameAs(mockDisplayInfoProvider) + assertThat( + timeseries.pipelines[1].getFieldValue>("customAttributes") + ).isSameAs(fakeCustomAttributes) } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt index bf39ce791b..6f44704c65 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt @@ -15,13 +15,15 @@ import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter import com.datadog.android.api.storage.EventBatchWriter import com.datadog.android.api.storage.EventType +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.domain.scope.RumViewType +import com.datadog.android.rum.internal.timeseries.factory.EventFactory import com.datadog.android.rum.internal.timeseries.provider.DataPointsReader -import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer import com.datadog.android.rum.utils.forge.Configurator import com.datadog.android.utils.verifyLog import com.google.gson.JsonObject import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.IntForgery import fr.xgouchet.elmyr.annotation.LongForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration @@ -49,6 +51,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.mockito.quality.Strictness +import java.util.UUID import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit @@ -81,6 +84,9 @@ internal class DefaultTimeseriesCollectorTest { @Mock lateinit var mockEventBatchWriter: EventBatchWriter + @Mock + lateinit var mockDatadogContext: DatadogContext + @Mock lateinit var mockExecutor: ScheduledExecutorService @@ -94,10 +100,10 @@ internal class DefaultTimeseriesCollectorTest { lateinit var mockReaderB: DataPointsReader @Mock - lateinit var mockSerializerA: JsonSerializer + lateinit var mockEventFactoryA: EventFactory @Mock - lateinit var mockSerializerB: JsonSerializer + lateinit var mockEventFactoryB: EventFactory private lateinit var bufferA: Buffer private lateinit var bufferB: Buffer @@ -114,6 +120,27 @@ internal class DefaultTimeseriesCollectorTest { @IntForgery(min = 2, max = 16) var fakeBufferSize: Int = 0 + @Forgery + lateinit var fakeRumContext: RumContext + + private fun fakeRumContextOf(viewType: RumViewType) = fakeRumContext.copy(viewType = viewType) + + private fun createTimeseries( + initialViewType: RumViewType, + pipelines: List> = listOf(pipelineA, pipelineB) + ) = DefaultTimeseriesCollector( + pipelines = pipelines, + internalLogger = mockInternalLogger, + scheduledExecutorService = mockExecutor, + rumContext = fakeRumContextOf(initialViewType) + ) + + // Single foreground pipeline wired to reader/event factory A, with a buffer the test controls. + private fun createTimeseriesWithBuffer(buffer: Buffer) = createTimeseries( + RumViewType.FOREGROUND, + listOf(Pipeline(mockSdkCore, mockReaderA, buffer, mockEventFactoryA, mockDataWriter, { emptyMap() })) + ) + @BeforeEach fun `set up`() { whenever(mockReaderA.intervalMs) doReturn fakeIntervalAMs @@ -123,22 +150,33 @@ internal class DefaultTimeseriesCollectorTest { whenever(mockSdkCore.getFeature(Feature.RUM_FEATURE_NAME)) doReturn mockRumFeatureScope whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { inv -> inv.getArgument<(DatadogContext, EventWriteScope) -> Unit>(inv.arguments.lastIndex) - .invoke(mock(), mockEventWriteScope) + .invoke(mockDatadogContext, mockEventWriteScope) } whenever(mockEventWriteScope.invoke(any())) doAnswer { inv -> inv.getArgument<(EventBatchWriter) -> Unit>(0).invoke(mockEventBatchWriter) } + whenever(mockEventFactoryA.eventName) doReturn "" + whenever(mockEventFactoryB.eventName) doReturn "" bufferA = Buffer(fakeBufferSize) bufferB = Buffer(fakeBufferSize) - pipelineA = Pipeline(mockSdkCore, mockReaderA, bufferA, mockSerializerA, mockDataWriter, mockInternalLogger) - pipelineB = Pipeline(mockSdkCore, mockReaderB, bufferB, mockSerializerB, mockDataWriter, mockInternalLogger) + pipelineA = Pipeline(mockSdkCore, mockReaderA, bufferA, mockEventFactoryA, mockDataWriter, { emptyMap() }) + pipelineB = Pipeline(mockSdkCore, mockReaderB, bufferB, mockEventFactoryB, mockDataWriter, { emptyMap() }) - testedTimeseries = createCollector(RumViewType.FOREGROUND) + testedTimeseries = createTimeseries(RumViewType.FOREGROUND) } - @Test - fun `M schedule one runnable per pipeline W onSessionStart()`() { + @ParameterizedTest + @EnumSource( + value = RumViewType::class, + names = ["FOREGROUND", "APPLICATION_LAUNCH"] + ) + fun `M schedule one runnable per pipeline W onSessionStart() { initial view is foreground }`( + initialViewType: RumViewType + ) { + // Given + testedTimeseries = createTimeseries(initialViewType) + // When testedTimeseries.onSessionStart() @@ -147,13 +185,55 @@ internal class DefaultTimeseriesCollectorTest { verify(mockExecutor).schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) } + @ParameterizedTest + @EnumSource( + value = RumViewType::class, + names = ["NONE", "BACKGROUND"] + ) + fun `M not schedule W onSessionStart() { initial view is not foreground }`( + initialViewType: RumViewType + ) { + // Given + testedTimeseries = createTimeseries(initialViewType) + + // When + testedTimeseries.onSessionStart() + + // Then + verify(mockExecutor, never()).schedule(any(), any(), any()) + } + @Test - fun `M not write events W onSessionStop() { never started }`() { + fun `M not schedule W onRumContextUpdate() { none to background }`() { + // Given + testedTimeseries = createTimeseries(RumViewType.NONE) + testedTimeseries.onSessionStart() + // When - testedTimeseries.onSessionStop() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + + // Then — neither a sampling chain nor a suspend: the app never left the foreground + verify(mockExecutor, never()).schedule(any(), any(), any()) + } + + @ParameterizedTest + @EnumSource( + value = RumViewType::class, + names = ["FOREGROUND", "APPLICATION_LAUNCH"] + ) + fun `M resume scheduling W onRumContextUpdate() { none to foreground }`( + foregroundViewType: RumViewType + ) { + // Given + testedTimeseries = createTimeseries(RumViewType.NONE) + testedTimeseries.onSessionStart() + + // When + testedTimeseries.onRumContextUpdate(fakeRumContextOf(foregroundViewType)) // Then - verify(mockDataWriter, never()).write(any(), any(), any()) + verify(mockExecutor).schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + verify(mockExecutor).schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) } @Test @@ -170,7 +250,7 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M not write events W onSessionStart()+onSessionStop() { buffers empty }`() { + fun `M not write events W onSessionStop() { nothing sampled }`() { // Given testedTimeseries.onSessionStart() @@ -182,39 +262,40 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M log error and continue W onSessionStop() { serializer throws on pipelineA }`(forge: Forge) { - // Given - val fakeError = RuntimeException("serializer failure") + fun `M log error and flush remaining pipelines W onSessionStop() { pipeline flush throws }`(forge: Forge) { + // Given — drain() throws outside Pipeline's own try/catch, so the failure surfaces in + // DefaultTimeseriesCollector.flushPipelines() and must not skip the remaining pipelines. + val fakeError = RuntimeException("drain failure") val fakeJson = JsonObject().apply { addProperty("k", "v") } - whenever(mockReaderA.read()) doReturn forge.getForgery>() + val mockBuffer = mock>() + whenever(mockBuffer.drain()) doThrow fakeError whenever(mockReaderB.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doThrow fakeError - whenever(mockSerializerB.serialize(any(), any())) doReturn fakeJson + whenever(mockEventFactoryB.create(any(), any(), any(), any())) doReturn fakeJson + val failingPipeline = + Pipeline(mockSdkCore, mockReaderA, mockBuffer, mockEventFactoryA, mockDataWriter, { emptyMap() }) + testedTimeseries = createTimeseries(RumViewType.FOREGROUND, listOf(failingPipeline, pipelineB)) testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - val runnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) - runnableA.run() - runnableB.run() + captureScheduledRunnableForInterval(fakeIntervalBMs).run() // buffers one sample for pipeline B // When testedTimeseries.onSessionStop() - // Then — error logged for pipelineA, pipelineB still flushed + // Then mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - "Timeseries serialization failed", + DefaultTimeseriesCollector.ERROR_FLUSH_FAILED, fakeError ) verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) } @Test - fun `M flush partial buffer W onSessionStop() { buffer below batch size }`(forge: Forge) { + fun `M flush partial buffer W onSessionStop() { buffer below capacity }`(forge: Forge) { // Given val fakeJson = JsonObject().apply { addProperty("k", "v") } whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doReturn fakeJson + whenever(mockEventFactoryA.create(any(), any(), any(), any())) doReturn fakeJson testedTimeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) runnableA.run() @@ -223,18 +304,18 @@ internal class DefaultTimeseriesCollectorTest { testedTimeseries.onSessionStop() // Then - verify(mockSerializerA).serialize(any(), any()) + verify(mockEventFactoryA).create(any(), any(), any(), any()) verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) } @Test - fun `M flush batch W sample tick fills buffer { single pipeline }`(forge: Forge) { + fun `M write batch W sample tick { buffer reaches capacity }`(forge: Forge) { // Given - val element = forge.getForgery>() - val dataPoints = List(fakeBufferSize) { element } + val fakePoint = forge.getForgery>() + val fakeDataPoints = List(fakeBufferSize) { fakePoint } val fakeJson = JsonObject().apply { addProperty("a", "1") } - whenever(mockReaderA.read()) doReturn element - whenever(mockSerializerA.serialize(any(), eq(dataPoints))) doReturn fakeJson + whenever(mockReaderA.read()) doReturn fakePoint + whenever(mockEventFactoryA.create(any(), any(), eq(fakeDataPoints), any())) doReturn fakeJson testedTimeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) @@ -243,7 +324,12 @@ internal class DefaultTimeseriesCollectorTest { repeat(fakeBufferSize) { runnableA.run() } // Then - verify(mockSerializerA).serialize(any(), any()) + verify(mockEventFactoryA).create( + eq(mockDatadogContext), + eq(fakeRumContextOf(RumViewType.FOREGROUND)), + eq(fakeDataPoints), + any() + ) verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) } @@ -270,26 +356,10 @@ internal class DefaultTimeseriesCollectorTest { val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) // When - runnableA.run() + repeat(fakeBufferSize - 1) { runnableA.run() } // Then - verify(mockSerializerA, never()).serialize(any(), any()) - verify(mockDataWriter, never()).write(any(), any(), any()) - } - - @Test - fun `M skip writer W sample tick { serializer returns null }`(forge: Forge) { - // Given - fill the buffer so Pipeline.drain() reaches the serializer; serializer returns null - whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doReturn null - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - repeat(fakeBufferSize) { runnableA.run() } - - // Then - verify(mockSerializerA).serialize(any(), any()) + verify(mockEventFactoryA, never()).create(any(), any(), any(), any()) verify(mockDataWriter, never()).write(any(), any(), any()) } @@ -313,37 +383,22 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M not throw W onSessionStop() { called twice }`() { + fun `M flush only once W onSessionStop() { called twice }`() { // Given + val mockBuffer = mock>() + testedTimeseries = createTimeseriesWithBuffer(mockBuffer) testedTimeseries.onSessionStart() - // When + Then — must not throw + // When testedTimeseries.onSessionStop() testedTimeseries.onSessionStop() - } - - @Test - fun `M continue scheduling W sample tick { reader throws }`() { - // Given - val fakeError = RuntimeException("reader failure") - whenever(mockReaderA.read()) doThrow fakeError - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - runnableA.run() - // Then — 1 from start() + 1 rescheduled via finally after exception - verify(mockExecutor, times(2)) - .schedule( - any(), - eq(fakeIntervalAMs), - eq(TimeUnit.MILLISECONDS) - ) + // Then — the second call sees the state already STOPPED and never reaches the pipelines + verify(mockBuffer).drain() } @Test - fun `M log error W sample tick { reader throws }`() { + fun `M log error and reschedule W sample tick { reader throws }`() { // Given val fakeError = RuntimeException("reader failure") whenever(mockReaderA.read()) doThrow fakeError @@ -353,28 +408,28 @@ internal class DefaultTimeseriesCollectorTest { // When runnableA.run() - // Then + // Then — 1 schedule from start() + 1 rescheduled via finally after the exception mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), DefaultTimeseriesCollector.ERROR_SAMPLING_FAILED, fakeError ) + verify(mockExecutor, times(2)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) } @Test fun `M log error and reschedule W sample tick { buffer drain throws }`(forge: Forge) { // Given — drain() throws outside Pipeline's own try/catch, so it must be - // caught by DefaultTimeseriesCollector' sampling try/catch instead. + // caught by DefaultTimeseriesCollector's sampling try/catch instead. val fakeError = RuntimeException("drain failure") val mockBuffer = mock>() whenever(mockBuffer.isFull()) doReturn true whenever(mockBuffer.drain()) doThrow fakeError whenever(mockReaderA.read()) doReturn forge.getForgery>() - val pipeline = - Pipeline(mockSdkCore, mockReaderA, mockBuffer, mockSerializerA, mockDataWriter, mockInternalLogger) - val timeseries = createCollector(RumViewType.FOREGROUND, listOf(pipeline)) - timeseries.onSessionStart() + testedTimeseries = createTimeseriesWithBuffer(mockBuffer) + testedTimeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) // When @@ -392,12 +447,12 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M log error and reschedule W sample tick { serializer throws }`(forge: Forge) { - // Given — serializer throws inside Pipeline's own try/catch: Pipeline logs it itself + fun `M log error and reschedule W sample tick { event factory throws }`(forge: Forge) { + // Given — event factory throws inside Pipeline's own try/catch: Pipeline logs it itself // and the tick completes normally, so the sampling chain reschedules as usual. - val fakeError = RuntimeException("serializer failure") + val fakeError = RuntimeException("event factory failure") whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doThrow fakeError + whenever(mockEventFactoryA.create(any(), any(), any(), any())) doThrow fakeError testedTimeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) @@ -405,12 +460,12 @@ internal class DefaultTimeseriesCollectorTest { repeat(fakeBufferSize) { runnableA.run() } // Then - // times(1) default on verifyLog also confirms this is the only ERROR log with that - // throwable — i.e. DefaultTimeseriesCollector' own sampling catch never fired here. + // verifyLog matches on `same(fakeError)`, so its default times(1) also proves the + // collector's own sampling catch never logged the same throwable a second time. mockInternalLogger.verifyLog( InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - "Timeseries serialization failed", + "Timeseries event creation failed", fakeError ) verify(mockDataWriter, never()).write(any(), any(), any()) @@ -443,8 +498,9 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M not reschedule W stopped { sample tick skips try block }`() { + fun `M not sample nor reschedule W sample tick { session stopped }`(forge: Forge) { // Given + whenever(mockReaderA.read()) doReturn forge.getForgery>() testedTimeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) testedTimeseries.onSessionStop() @@ -452,7 +508,8 @@ internal class DefaultTimeseriesCollectorTest { // When runnableA.run() - // Then — no additional schedule after the one from start() + // Then — sample skipped AND no additional schedule after the one from start() + verify(mockReaderA, never()).read() verify(mockExecutor).schedule( any(), eq(fakeIntervalAMs), @@ -461,133 +518,170 @@ internal class DefaultTimeseriesCollectorTest { } @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) - fun `M not schedule W onSessionStart() { initial view is not foreground }`( - initialViewType: RumViewType - ) { - // Given - val timeseries = createCollector(initialViewType) - - // When - timeseries.onSessionStart() - - // Then - verify(mockExecutor, never()).schedule(any(), any(), any()) - } - - @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["FOREGROUND", "APPLICATION_LAUNCH"]) - fun `M neither flush nor schedule suspend W onViewTypeUpdate() { stays foreground }`( + @EnumSource( + value = RumViewType::class, + names = ["FOREGROUND", "APPLICATION_LAUNCH"] + ) + fun `M neither flush nor schedule suspend W onRumContextUpdate() { stays foreground }`( nextViewType: RumViewType, forge: Forge ) { // Given + val fakeNextContext = fakeRumContextOf(nextViewType).copy(viewId = forge.getForgery().toString()) whenever(mockReaderA.read()) doReturn forge.getForgery>() testedTimeseries.onSessionStart() captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A // When - testedTimeseries.onViewTypeUpdate(nextViewType) + testedTimeseries.onRumContextUpdate(fakeNextContext) // Then — no suspend is even scheduled, so nothing can flush later either verify(mockExecutor, never()) .schedule(any(), eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), eq(TimeUnit.MILLISECONDS)) - verifyNoInteractions(mockSerializerA) + verifyNoInteractions(mockEventFactoryA) verifyNoInteractions(mockDataWriter) } @Test - fun `M not flush W onViewTypeUpdate() { suspend not fired yet }`(forge: Forge) { + fun `M use updated context W sample tick fills buffer { foreground view changed }`(forge: Forge) { // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() + val fakePoint = forge.getForgery>() + val fakeNextContext = fakeRumContextOf(RumViewType.FOREGROUND).copy( + viewId = forge.getForgery().toString() + ) + whenever(mockReaderA.read()) doReturn fakePoint + whenever(mockEventFactoryA.create(any(), eq(fakeNextContext), any(), any())) doReturn JsonObject() testedTimeseries.onSessionStart() - captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A + testedTimeseries.onRumContextUpdate(fakeNextContext) + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - // When — leaving the foreground only schedules the suspend, it does not flush inline - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + // When + repeat(fakeBufferSize) { runnableA.run() } // Then - verify(mockExecutor) - .schedule(any(), eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), eq(TimeUnit.MILLISECONDS)) - verifyNoInteractions(mockSerializerA) - verifyNoInteractions(mockDataWriter) + verify(mockEventFactoryA).create(any(), eq(fakeNextContext), eq(List(fakeBufferSize) { fakePoint }), any()) + } + + @Test + fun `M suspend chain W sample tick { suspend fired after background }`(forge: Forge) { + // Given + whenever(mockReaderA.read()) doReturn forge.getForgery>() + testedTimeseries.onSessionStart() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + runScheduledSuspend() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + runnableA.run() + + // Then — sample skipped AND no reschedule (chain suspended) + verify(mockReaderA, never()).read() + verify(mockExecutor).schedule( + any(), + eq(fakeIntervalAMs), + eq(TimeUnit.MILLISECONDS) + ) } @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) - fun `M flush partial buffer W pending suspend fires { left foreground }`( + @EnumSource( + value = RumViewType::class, + names = ["NONE", "BACKGROUND"] + ) + fun `M flush partial buffer with last foreground context W pending suspend fires { left foreground }`( nextViewType: RumViewType, forge: Forge ) { // Given val fakeSample = forge.getForgery>() - val fakeJson = JsonObject().apply { addProperty("fake-key", "fake-value") } + val fakeJson = JsonObject().apply { addProperty("k", "v") } whenever(mockReaderA.read()) doReturn fakeSample - whenever(mockSerializerA.serialize(any(), eq(listOf(fakeSample)))) doReturn fakeJson + whenever( + mockEventFactoryA.create( + eq(mockDatadogContext), + eq(fakeRumContextOf(RumViewType.FOREGROUND)), + eq(listOf(fakeSample)), + any() + ) + ) doReturn fakeJson testedTimeseries.onSessionStart() captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A - testedTimeseries.onViewTypeUpdate(nextViewType) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(nextViewType)) // When runScheduledSuspend() - // Then — the batch buffered while in the foreground still reaches the writer - verify(mockSerializerA).serialize(any(), eq(listOf(fakeSample))) + // Then — the batch is stamped with the view the user was looking at, not the new one + verify(mockEventFactoryA).create( + eq(mockDatadogContext), + eq(fakeRumContextOf(RumViewType.FOREGROUND)), + eq(listOf(fakeSample)), + any() + ) verify(mockDataWriter).write(mockEventBatchWriter, fakeJson, EventType.DEFAULT) - // pipeline B never sampled, so its empty buffer must not produce an event - verify(mockSerializerB, never()).serialize(any(), any()) + verify(mockEventFactoryB, never()).create(any(), any(), any(), any()) } @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) - fun `M flush W onSessionStop() { left foreground, suspend pending }`( + @EnumSource( + value = RumViewType::class, + names = ["NONE", "BACKGROUND"] + ) + fun `M flush with last foreground context W onSessionStop() { left foreground, suspend pending }`( nextViewType: RumViewType, forge: Forge ) { // Given val fakeSample = forge.getForgery>() whenever(mockReaderA.read()) doReturn fakeSample - whenever(mockSerializerA.serialize(any(), any())) doReturn JsonObject() + whenever(mockEventFactoryA.create(any(), any(), any(), any())) doReturn JsonObject() testedTimeseries.onSessionStart() captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A - testedTimeseries.onViewTypeUpdate(nextViewType) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(nextViewType)) // When — the session is stopped before the pending suspend had a chance to flush testedTimeseries.onSessionStop() - // Then - verify(mockSerializerA).serialize(any(), eq(listOf(fakeSample))) + // Then — same attribution as the suspend path, not the background context + verify(mockEventFactoryA).create( + eq(mockDatadogContext), + eq(fakeRumContextOf(RumViewType.FOREGROUND)), + eq(listOf(fakeSample)), + any() + ) } @Test - fun `M not flush twice W pending suspend fires { session already stopped }`() { + fun `M not flush W onRumContextUpdate() { suspend not fired yet }`(forge: Forge) { // Given - val mockBuffer = mock>() - val pipeline = - Pipeline(mockSdkCore, mockReaderA, mockBuffer, mockSerializerA, mockDataWriter, mockInternalLogger) - val timeseries = createCollector(RumViewType.FOREGROUND, listOf(pipeline)) - timeseries.onSessionStart() - timeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - timeseries.onSessionStop() // drains the buffer synchronously + whenever(mockReaderA.read()) doReturn forge.getForgery>() + testedTimeseries.onSessionStart() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A - // When - runScheduledSuspend() + // When — leaving the foreground only schedules the suspend, it does not flush inline + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) - // Then — the pending suspend targets a stale generation and must not drain again - verify(mockBuffer).drain() + // Then + verify(mockExecutor) + .schedule(any(), eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), eq(TimeUnit.MILLISECONDS)) + verifyNoInteractions(mockEventFactoryA) + verifyNoInteractions(mockDataWriter) } @ParameterizedTest - @EnumSource(value = RumViewType::class, names = ["NONE", "BACKGROUND"]) + @EnumSource( + value = RumViewType::class, + names = ["NONE", "BACKGROUND"] + ) fun `M skip sample and reschedule W sample tick { foreground exit is pending }`( nextViewType: RumViewType ) { // Given testedTimeseries.onSessionStart() val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - testedTimeseries.onViewTypeUpdate(nextViewType) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(nextViewType)) - // When — the suspend has not fired yet, so the chain is still alive + // When runnableA.run() // Then @@ -597,48 +691,48 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M suspend chain W sample tick { suspend fired after background }`(forge: Forge) { + fun `M keep sampling chain W stale suspend fires { foreground re-entered then left }`() { // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - runScheduledSuspend() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) + val staleSuspend = captureScheduledSuspendRunnable() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) + val currentRunnableA = captureLastScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) // When - runnableA.run() + staleSuspend.run() + currentRunnableA.run() - // Then — sample skipped AND no reschedule (chain suspended) + // Then + verify(mockDataWriter, never()).write(any(), any(), any()) verify(mockReaderA, never()).read() - verify(mockExecutor).schedule( - any(), - eq(fakeIntervalAMs), - eq(TimeUnit.MILLISECONDS) - ) + verify(mockExecutor, times(3)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) } @Test - fun `M cancel pending suspend W onViewTypeUpdate() { foreground re-entered }`() { + fun `M cancel pending suspend W onRumContextUpdate() { foreground re-entered }`() { // Given testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.NONE) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) // When - testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) // Then verify(mockScheduledFuture).cancel(false) } @Test - fun `M schedule suspend once W onViewTypeUpdate() { repeated non-foreground updates }`() { + fun `M schedule suspend once W onRumContextUpdate() { repeated non-foreground updates }`() { // Given testedTimeseries.onSessionStart() // When - testedTimeseries.onViewTypeUpdate(RumViewType.NONE) - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - testedTimeseries.onViewTypeUpdate(RumViewType.NONE) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) // Then verify(mockExecutor).schedule( @@ -649,38 +743,33 @@ internal class DefaultTimeseriesCollectorTest { } @Test - fun `M keep sampling chain W stale suspend fires { foreground re-entered then left }`() { + fun `M not flush twice W pending suspend fires { session already stopped }`() { // Given + val mockBuffer = mock>() + testedTimeseries = createTimeseriesWithBuffer(mockBuffer) testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.NONE) - val staleSuspend = captureScheduledSuspendRunnable() - testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) - val currentRunnableA = captureLastScheduledRunnableForInterval(fakeIntervalAMs) - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + testedTimeseries.onSessionStop() // drains the buffer synchronously - // When — the suspend from the first exit fires against a generation that moved on - staleSuspend.run() - currentRunnableA.run() + // When + runScheduledSuspend() - // Then — nothing flushed, and the live chain keeps rescheduling - verify(mockDataWriter, never()).write(any(), any(), any()) - verify(mockReaderA, never()).read() - verify(mockExecutor, times(3)) - .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + // Then — the pending suspend loses the CAS against STOPPED and does nothing + verify(mockBuffer).drain() } @Test - fun `M resume scheduling W onViewTypeUpdate() { background to foreground }`() { + fun `M resume scheduling W onRumContextUpdate() { background to foreground }`() { // Given — the deferred suspend fired, so the next tick dies without rescheduling testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) runScheduledSuspend() captureScheduledRunnableForInterval(fakeIntervalAMs).run() verify(mockExecutor, times(1)) .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) // When — app returns to foreground - testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) // Then — scheduling resumed, one new schedule per pipeline verify(mockExecutor, times(2)) @@ -692,35 +781,26 @@ internal class DefaultTimeseriesCollectorTest { @Test fun `M not sample nor reschedule W stale tick fires { new generation is running }`() { // Regression: a tick from the generation that was alive before the suspend must - // self-terminate on the generation check, even though the state is running again. + // self-terminate on the generation check, even though the state is RUNNING again. // // Given testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) runScheduledSuspend() val staleRunnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) - // Resume: a fresh generation is running; A and B each get a new schedule - testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) + // Resume: state = RUNNING, generation = 2; A and B each get a fresh schedule + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) - // When — B's stale tick fires + // When — B's stale generation-1 tick fires while state is RUNNING staleRunnableB.run() // Then — stale tick neither samples nor produces an extra schedule verify(mockReaderB, never()).read() + // B schedules: 1 from start() + 1 from the resume = 2; the stale tick adds nothing verify(mockExecutor, times(2)) .schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) } - private fun createCollector( - initialViewType: RumViewType, - pipelines: List> = listOf(pipelineA, pipelineB) - ) = DefaultTimeseriesCollector( - pipelines = pipelines, - internalLogger = mockInternalLogger, - scheduledExecutorService = mockExecutor, - currentViewType = initialViewType - ) - private fun runScheduledSuspend() { captureScheduledSuspendRunnable().run() } @@ -732,15 +812,15 @@ internal class DefaultTimeseriesCollectorTest { return captor.lastValue } - private fun captureLastScheduledRunnableForInterval(intervalMs: Long): Runnable { - val captor = argumentCaptor() - verify(mockExecutor, atLeastOnce()).schedule(captor.capture(), eq(intervalMs), eq(TimeUnit.MILLISECONDS)) - return captor.lastValue - } - private fun captureScheduledRunnableForInterval(intervalMs: Long): Runnable { val captor = argumentCaptor() verify(mockExecutor).schedule(captor.capture(), eq(intervalMs), eq(TimeUnit.MILLISECONDS)) return captor.firstValue } + + private fun captureLastScheduledRunnableForInterval(intervalMs: Long): Runnable { + val captor = argumentCaptor() + verify(mockExecutor, atLeastOnce()).schedule(captor.capture(), eq(intervalMs), eq(TimeUnit.MILLISECONDS)) + return captor.lastValue + } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/PipelineTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/PipelineTest.kt index 3dfee43c74..d5cece9078 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/PipelineTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/PipelineTest.kt @@ -15,17 +15,20 @@ import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.api.storage.DataWriter import com.datadog.android.api.storage.EventBatchWriter import com.datadog.android.api.storage.EventType +import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector +import com.datadog.android.rum.internal.timeseries.factory.EventFactory import com.datadog.android.rum.internal.timeseries.provider.DataPointsReader -import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer import com.datadog.android.rum.internal.timeseries.serializer.TimeseriesAttributes import com.datadog.android.rum.utils.forge.Configurator import com.datadog.android.utils.verifyLog import com.datadog.tools.unit.forge.aThrowable import com.google.gson.JsonObject import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.IntForgery import fr.xgouchet.elmyr.annotation.LongForgery +import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat @@ -46,6 +49,11 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.mockito.quality.Strictness +import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.CountDownLatch +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicLong @Extensions( ExtendWith(MockitoExtension::class), @@ -55,11 +63,14 @@ import org.mockito.quality.Strictness @ForgeConfiguration(Configurator::class) internal class PipelineTest { + @Forgery + lateinit var fakeRumContext: RumContext + @Mock lateinit var mockReader: DataPointsReader @Mock - lateinit var mockSerializer: JsonSerializer + lateinit var mockEventFactory: EventFactory @Mock lateinit var mockSdkCore: FeatureSdkCore @@ -88,11 +99,20 @@ internal class PipelineTest { @IntForgery(min = 2, max = 10) var fakeBufferSize: Int = 0 + @StringForgery + lateinit var fakeAttributeKey: String + + @StringForgery + lateinit var fakeAttributeValue: String + + private var fakeCustomAttributes: Map = emptyMap() + private lateinit var buffer: Buffer private lateinit var testedPipeline: Pipeline @BeforeEach fun `set up`() { + whenever(mockSdkCore.internalLogger) doReturn mockInternalLogger whenever(mockSdkCore.getFeature(Feature.RUM_FEATURE_NAME)) doReturn mockRumFeatureScope whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { it.getArgument<(DatadogContext, EventWriteScope) -> Unit>(it.arguments.lastIndex) @@ -102,15 +122,17 @@ internal class PipelineTest { it.getArgument<(EventBatchWriter) -> Unit>(0).invoke(mockEventBatchWriter) } whenever(mockDataWriter.write(any(), any(), any())) doReturn true + whenever(mockEventFactory.eventName) doReturn "view.cpu" + fakeCustomAttributes = mapOf(fakeAttributeKey to fakeAttributeValue) buffer = Buffer(fakeBufferSize) testedPipeline = Pipeline( sdkCore = mockSdkCore, reader = mockReader, buffer = buffer, - serializer = mockSerializer, + eventFactory = mockEventFactory, dataWriter = mockDataWriter, - internalLogger = mockInternalLogger, + customAttributes = { fakeCustomAttributes }, insightsCollector = mockInsightsCollector ) } @@ -133,7 +155,7 @@ internal class PipelineTest { whenever(mockReader.read()) doReturn fakePoint // When - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // Then assertThat(buffer.drain()).containsExactly(fakePoint) @@ -145,12 +167,35 @@ internal class PipelineTest { whenever(mockReader.read()) doReturn null // When - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // Then assertThat(buffer.drain()).isEmpty() } + @Test + fun `M not hold the lock while reading W execute()`(forge: Forge) { + // Given — a concurrent flush() races the reader and must not wait for the read to finish + var flushedWhileReading = false + whenever(mockReader.read()) doAnswer { + val flushed = CountDownLatch(1) + Thread { + testedPipeline.flush(fakeRumContext) + flushed.countDown() + }.start() + flushedWhileReading = flushed.await(CONCURRENT_FLUSH_TIMEOUT_MS, TimeUnit.MILLISECONDS) + forge.getForgery>() + } + + // When + testedPipeline.execute(fakeRumContext) + + // Then + assertThat(flushedWhileReading) + .describedAs("flush() completed while reader.read() was still running") + .isTrue() + } + // endregion // region flush() @@ -162,11 +207,12 @@ internal class PipelineTest { val fakeTimeseriesName = "view.cpu" val fakeJson = fakeTimeseriesJson(fakeTimeseriesName) whenever(mockReader.read()) doReturn fakePoint - whenever(mockSerializer.serialize(any(), any())) doReturn fakeJson - repeat(fakeBufferSize - 1) { testedPipeline.execute() } + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeJson + whenever(mockEventFactory.eventName) doReturn fakeTimeseriesName + repeat(fakeBufferSize - 1) { testedPipeline.execute(fakeRumContext) } // When - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // Then verify(mockDataWriter).write(mockEventBatchWriter, fakeJson, EventType.DEFAULT) @@ -180,7 +226,7 @@ internal class PipelineTest { whenever(mockReader.read()) doReturn forge.getForgery>() // When - repeat(fakeBufferSize - 1) { testedPipeline.execute() } + repeat(fakeBufferSize - 1) { testedPipeline.execute(fakeRumContext) } // Then verifyNoInteractions(mockDataWriter) @@ -188,14 +234,14 @@ internal class PipelineTest { } @Test - fun `M not flush W execute() { serializer returns null }`(forge: Forge) { + fun `M not flush W execute() { event factory returns null }`(forge: Forge) { // Given whenever(mockReader.read()) doReturn forge.getForgery>() - whenever(mockSerializer.serialize(any(), any())) doReturn null - repeat(fakeBufferSize - 1) { testedPipeline.execute() } + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn null + repeat(fakeBufferSize - 1) { testedPipeline.execute(fakeRumContext) } // When - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // Then verifyNoInteractions(mockDataWriter) @@ -213,16 +259,17 @@ internal class PipelineTest { val fakeTimeseriesName = "view.memory" val fakeJson = fakeTimeseriesJson(fakeTimeseriesName) whenever(mockReader.read()) doReturn fakePoint - whenever(mockSerializer.serialize(any(), any())) doReturn fakeJson + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeJson + whenever(mockEventFactory.eventName) doReturn fakeTimeseriesName val sampleCount = fakeBufferSize - 1 - repeat(sampleCount) { testedPipeline.execute() } + repeat(sampleCount) { testedPipeline.execute(fakeRumContext) } // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) // Then val captor = argumentCaptor>>() - verify(mockSerializer).serialize(any(), captor.capture()) + verify(mockEventFactory).create(any(), eq(fakeRumContext), captor.capture(), any()) assertThat(captor.firstValue).hasSize(sampleCount).allMatch { it == fakePoint } verify(mockDataWriter).write(mockEventBatchWriter, fakeJson, EventType.DEFAULT) verify(mockInsightsCollector).onTimeseries(fakeTimeseriesName) @@ -234,22 +281,22 @@ internal class PipelineTest { // Given val fakePoint = forge.getForgery>() whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { Unit } - whenever(mockSerializer.serialize(any(), any())) doReturn fakeTimeseriesJson("view.cpu") + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeTimeseriesJson("view.cpu") whenever(mockReader.read()) doReturn fakePoint - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) // Then assertThat(buffer.drain()).isEmpty() - verifyNoInteractions(mockSerializer) + verifyNoInteractions(mockEventFactory) verifyNoInteractions(mockDataWriter) verifyNoInteractions(mockInsightsCollector) } @Test - fun `M pass only pre-flush points to serializer W execute() { point added before write context callback invoked }`( + fun `M pass pre-flush points to event factory W execute() { point added before callback }`( forge: Forge ) { // Given @@ -257,42 +304,80 @@ internal class PipelineTest { val fakeNextPoint = forge.getForgery>() val callbackCaptor = argumentCaptor<(DatadogContext, EventWriteScope) -> Unit>() whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { Unit } - whenever(mockSerializer.serialize(any(), any())) doReturn fakeTimeseriesJson("view.cpu") + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeTimeseriesJson("view.cpu") whenever(mockReader.read()) doReturn fakePoint - testedPipeline.execute() - testedPipeline.flush() + testedPipeline.execute(fakeRumContext) + testedPipeline.flush(fakeRumContext) whenever(mockReader.read()) doReturn fakeNextPoint // When - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) verify(mockRumFeatureScope).withWriteContext(any(), callbackCaptor.capture()) callbackCaptor.firstValue.invoke(mockDatadogContext, mockEventWriteScope) // Then val dataPointsCaptor = argumentCaptor>>() - verify(mockSerializer).serialize(eq(mockDatadogContext), dataPointsCaptor.capture()) + verify(mockEventFactory).create(eq(mockDatadogContext), eq(fakeRumContext), dataPointsCaptor.capture(), any()) assertThat(dataPointsCaptor.firstValue).containsExactly(fakePoint) assertThat(buffer.drain()).containsExactly(fakeNextPoint) } @Test - fun `M pass datadogContext from withWriteContext W flush()`(forge: Forge) { + fun `M pass contexts to event factory W flush()`(forge: Forge) { + // Given + whenever(mockReader.read()) doReturn forge.getForgery>() + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeTimeseriesJson("view.cpu") + testedPipeline.execute(fakeRumContext) + + // When + testedPipeline.flush(fakeRumContext) + + // Then + verify(mockEventFactory).create(eq(mockDatadogContext), eq(fakeRumContext), any(), any()) + } + + @Test + fun `M resolve custom attributes before write context callback W flush()`(forge: Forge) { + // Given — attributes must be read while flushing, not when the deferred callback creates the event: + // by then the RUM monitor owning them may already be gone. + val callbackCaptor = argumentCaptor<(DatadogContext, EventWriteScope) -> Unit>() + whenever(mockRumFeatureScope.withWriteContext(any(), any())) doAnswer { Unit } + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeTimeseriesJson("view.cpu") + whenever(mockReader.read()) doReturn forge.getForgery>() + testedPipeline.execute(fakeRumContext) + val expectedAttributes = fakeCustomAttributes + + // When + testedPipeline.flush(fakeRumContext) + fakeCustomAttributes = emptyMap() + verify(mockRumFeatureScope).withWriteContext(any(), callbackCaptor.capture()) + callbackCaptor.firstValue.invoke(mockDatadogContext, mockEventWriteScope) + + // Then + verify(mockEventFactory).create(any(), any(), any(), eq(expectedAttributes)) + } + + @Test + fun `M request event creation feature contexts W flush()`(forge: Forge) { // Given whenever(mockReader.read()) doReturn forge.getForgery>() - whenever(mockSerializer.serialize(any(), any())) doReturn fakeTimeseriesJson("view.cpu") - testedPipeline.execute() + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeTimeseriesJson("view.cpu") + testedPipeline.execute(fakeRumContext) // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) // Then - verify(mockSerializer).serialize(eq(mockDatadogContext), any()) + verify(mockRumFeatureScope).withWriteContext( + eq(setOf(Feature.SESSION_REPLAY_FEATURE_NAME, Feature.TRACING_FEATURE_NAME)), + any() + ) } @Test fun `M not write W flush() { buffer empty }`() { // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) // Then verifyNoInteractions(mockDataWriter) @@ -300,21 +385,21 @@ internal class PipelineTest { } @Test - fun `M log error W flush() { serializer throws }`(forge: Forge) { + fun `M log error W flush() { event factory throws }`(forge: Forge) { // Given val fakeThrowable = forge.aThrowable() whenever(mockReader.read()) doReturn forge.getForgery>() - whenever(mockSerializer.serialize(any(), any())) doThrow fakeThrowable - testedPipeline.execute() + whenever(mockEventFactory.create(any(), any(), any(), any())) doThrow fakeThrowable + testedPipeline.execute(fakeRumContext) // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) // Then mockInternalLogger.verifyLog( level = InternalLogger.Level.ERROR, targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - message = "Timeseries serialization failed", + message = "Timeseries event creation failed", throwable = fakeThrowable ) verifyNoInteractions(mockDataWriter) @@ -328,13 +413,13 @@ internal class PipelineTest { val fakeJson = fakeTimeseriesJson("view.cpu") val writeBlockCaptor = argumentCaptor<(EventBatchWriter) -> Unit>() whenever(mockReader.read()) doReturn forge.getForgery>() - whenever(mockSerializer.serialize(any(), any())) doReturn fakeJson + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeJson whenever(mockDataWriter.write(any(), any(), any())) doThrow fakeThrowable whenever(mockEventWriteScope.invoke(any())) doAnswer { Unit } - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) verify(mockEventWriteScope).invoke(writeBlockCaptor.capture()) writeBlockCaptor.firstValue.invoke(mockEventBatchWriter) @@ -353,12 +438,12 @@ internal class PipelineTest { // Given val fakeJson = fakeTimeseriesJson("view.cpu") whenever(mockReader.read()) doReturn forge.getForgery>() - whenever(mockSerializer.serialize(any(), any())) doReturn fakeJson + whenever(mockEventFactory.create(any(), any(), any(), any())) doReturn fakeJson whenever(mockDataWriter.write(any(), any(), any())) doReturn false - testedPipeline.execute() + testedPipeline.execute(fakeRumContext) // When - testedPipeline.flush() + testedPipeline.flush(fakeRumContext) // Then verify(mockDataWriter).write(mockEventBatchWriter, fakeJson, EventType.DEFAULT) @@ -367,12 +452,127 @@ internal class PipelineTest { // endregion + // region concurrency + + @Test + fun `M not lose or duplicate points W execute() { concurrent samplers }`() { + // Given — every read() yields a unique point, every drained batch is recorded + val counter = AtomicLong() + val batches = CopyOnWriteArrayList>>() + stubUniqueReads(counter) + stubBatchRecording(batches) + + // When + runConcurrently { testedPipeline.execute(fakeRumContext) } + val batchesBeforeFlush = batches.toList() + testedPipeline.flush(fakeRumContext) + + // Then + assertThat(batchesBeforeFlush.map { it.size }) + .describedAs("batches drained by execute() are always exactly one buffer worth") + .containsOnly(fakeBufferSize) + assertThat(batches.flatten().map { it.timestampNs }.sorted()) + .isEqualTo((1L..counter.get()).toList()) + } + + @Test + fun `M not lose or duplicate points W execute() and flush() { concurrent }`() { + // Given + val counter = AtomicLong() + val batches = CopyOnWriteArrayList>>() + stubUniqueReads(counter) + stubBatchRecording(batches) + + // When — one thread keeps flushing while the others keep sampling + runConcurrently { threadIndex -> + if (threadIndex == 0) { + testedPipeline.flush(fakeRumContext) + } else { + testedPipeline.execute(fakeRumContext) + } + } + testedPipeline.flush(fakeRumContext) + + // Then + assertThat(batches.flatten().map { it.timestampNs }.sorted()) + .isEqualTo((1L..counter.get()).toList()) + } + + @Test + fun `M eventually capture point W flush() races execute() { flush between read() and add() }`( + forge: Forge + ) { + // Given — reader.read() blocks until released, forcing execute() to sit between + // its (unsynchronized) read() and the synchronized buffer add() + val readStarted = CountDownLatch(1) + val releaseRead = CountDownLatch(1) + val fakePoint = forge.getForgery>() + whenever(mockReader.read()) doAnswer { + readStarted.countDown() + releaseRead.await(CONCURRENT_FLUSH_TIMEOUT_MS, TimeUnit.MILLISECONDS) + fakePoint + } + val batches = CopyOnWriteArrayList>>() + stubBatchRecording(batches) + val executor = Executors.newSingleThreadExecutor() + + // When + executor.execute { testedPipeline.execute(fakeRumContext) } + readStarted.await(CONCURRENT_FLUSH_TIMEOUT_MS, TimeUnit.MILLISECONDS) + testedPipeline.flush(fakeRumContext) // races execute(): read() is in flight, not yet added + releaseRead.countDown() + executor.shutdown() + check(executor.awaitTermination(CONCURRENT_FLUSH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { + "execute() did not complete in time" + } + testedPipeline.flush(fakeRumContext) // point survives for the next flush + + // Then + assertThat(batches.flatten()).containsExactly(fakePoint) + } + + // endregion + + private fun stubUniqueReads(counter: AtomicLong) { + whenever(mockReader.read()) doAnswer { DataPoint(counter.incrementAndGet(), 0.0) } + } + + private fun stubBatchRecording(batches: MutableList>>) { + whenever(mockEventFactory.create(any(), any(), any(), any())) doAnswer { invocation -> + batches.add(invocation.getArgument(2)) + fakeTimeseriesJson("view.cpu") + } + } + + private fun runConcurrently(task: (threadIndex: Int) -> Unit) { + val executor = Executors.newFixedThreadPool(CONCURRENT_THREADS) + val start = CountDownLatch(1) + val done = CountDownLatch(CONCURRENT_THREADS) + repeat(CONCURRENT_THREADS) { threadIndex -> + executor.execute { + start.await() + repeat(ITERATIONS_PER_THREAD) { task(threadIndex) } + done.countDown() + } + } + start.countDown() + val finished = done.await(CONCURRENT_FLUSH_TIMEOUT_MS, TimeUnit.MILLISECONDS) + executor.shutdownNow() + check(finished) { "concurrent tasks did not complete in time" } + } + private fun fakeTimeseriesJson(name: String): JsonObject = JsonObject().apply { add( TimeseriesAttributes.KEY_TIMESERIES, JsonObject().apply { - addProperty("name", name) + addProperty(TimeseriesAttributes.KEY_NAME, name) } ) } + + private companion object { + const val CONCURRENT_FLUSH_TIMEOUT_MS = 2000L + const val CONCURRENT_THREADS = 4 + const val ITERATIONS_PER_THREAD = 200 + } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CSVReader.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CSVReader.kt index 2944e34a7e..d4ba3b6859 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CSVReader.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CSVReader.kt @@ -29,9 +29,6 @@ internal class CSVReader( fun hasNext(): Boolean = index < samples.size - /** Total number of samples available for the metric. */ - val size: Int get() = samples.size - override fun read(): DataPoint { check(hasNext()) { "CSVReader exhausted" } return samples[index++] diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt index d61f8175fb..277ca06f10 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt @@ -6,25 +6,36 @@ package com.datadog.android.rum.internal.timeseries.csv +import com.datadog.android.api.InternalLogger import com.datadog.android.api.context.DatadogContext import com.datadog.android.internal.time.TimeProvider import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.domain.scope.RumViewType +import com.datadog.android.rum.internal.domain.InfoData +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.domain.event.RumEventSerializer import com.datadog.android.rum.internal.timeseries.Buffer import com.datadog.android.rum.internal.timeseries.TimeseriesCollector -import com.datadog.android.rum.internal.timeseries.serializer.CpuEventSerializer -import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer -import com.datadog.android.rum.internal.timeseries.serializer.MemoryEventSerializer +import com.datadog.android.rum.internal.timeseries.factory.CpuEventFactory +import com.datadog.android.rum.internal.timeseries.factory.EventFactory +import com.datadog.android.rum.internal.timeseries.factory.MemoryEventFactory import com.google.gson.JsonObject +import com.google.gson.JsonParser +import fr.xgouchet.elmyr.Forge /** - * A test-only [Timeseries] that mirrors the wiring done by `DefaultTimeseriesCollectorFactory`, + * A test-only [TimeseriesCollector] that mirrors the wiring done by `DefaultTimeseriesFactory`, * but pulls samples from CSV-backed readers instead of `VitalReaderWrapper` and drives the * pipelines synchronously (no executor) so callers can assert on every emitted JSON. */ internal class CsvCollector( - private val pipelines: List, JsonSerializer>>, - private val datadogContext: DatadogContext + private val pipelines: List, EventFactory>>, + private val datadogContext: DatadogContext, + private val rumContext: RumContext, + private val customAttributes: Map, + private val eventSerializer: RumEventSerializer ) : TimeseriesCollector { private val emitted = mutableListOf() @@ -33,73 +44,92 @@ internal class CsvCollector( val captured: List get() = emitted.toList() /** - * Walks each (reader, buffer, serializer) triple synchronously: samples until the reader is + * Walks each (reader, buffer, factory) triple synchronously: samples until the reader is * exhausted, flushing whenever the buffer is full, then emitting any final remainder. */ override fun onSessionStart() { - for ((reader, buffer, serializer) in pipelines) { + for ((reader, buffer, eventFactory) in pipelines) { while (reader.hasNext()) { buffer.add(reader.read()) - if (buffer.isFull()) flush(buffer, serializer) + if (buffer.isFull()) flush(buffer, eventFactory) } - flush(buffer, serializer) + flush(buffer, eventFactory) } } - private fun flush(buffer: Buffer, serializer: JsonSerializer) = buffer.drain() + private fun flush(buffer: Buffer, eventFactory: EventFactory) = buffer.drain() .takeIf { it.isNotEmpty() } - ?.let { serializer.serialize(datadogContext, it) } - ?.let(emitted::add) + ?.let { eventFactory.create(datadogContext, rumContext, it, customAttributes) } + ?.let(eventSerializer::serialize) + ?.let(JsonParser::parseString) + ?.let { emitted.add(it.asJsonObject) } override fun onSessionStop() = Unit - override fun onViewTypeUpdate(newViewType: RumViewType) = Unit + override fun onRumContextUpdate(newRumContext: RumContext) = Unit companion object { /** - * Builds a [CsvCollector] with the same shape as `DefaultTimeseriesCollectorFactory`: + * Builds a [CsvCollector] with the same shape as `DefaultTimeseriesFactory`: * a memory pipeline followed by a CPU pipeline, each backed by [CSVReader] and the - * production [MemoryEventSerializer] / [CpuEventSerializer]. + * production [MemoryEventFactory] / [CpuEventFactory]. */ - @Suppress("LongParameterList") fun create( csvContent: String, - sessionId: String, - applicationId: String, sessionType: RumSessionType, totalRamBytes: Long, bufferSize: Int, timeProvider: TimeProvider, - datadogContext: DatadogContext - ) = CsvCollector( - datadogContext = datadogContext, - pipelines = listOf( - Triple( - CSVReader(csvContent, METRIC_MEMORY_USAGE, timeProvider), - Buffer(bufferSize), - MemoryEventSerializer( - sessionId = sessionId, - applicationId = applicationId, - sessionType = sessionType, - totalRamBytes = totalRamBytes, - timeProvider = timeProvider - ) - ), - Triple( - CSVReader(csvContent, METRIC_CPU_USAGE, timeProvider), - Buffer(bufferSize), - CpuEventSerializer( - sessionId = sessionId, - applicationId = applicationId, - sessionType = sessionType, - timeProvider = timeProvider + forge: Forge, + internalLogger: InternalLogger + ): CsvCollector { + val rumContext = forge.getForgery() + val datadogContext = forge.getForgery() + val batteryInfo = forge.getForgery() + val displayInfo = forge.getForgery() + + return CsvCollector( + datadogContext = datadogContext, + rumContext = rumContext, + customAttributes = CUSTOM_ATTRIBUTES, + eventSerializer = RumEventSerializer(internalLogger), + pipelines = listOf( + Triple( + CSVReader(csvContent, METRIC_MEMORY_USAGE, timeProvider), + Buffer(bufferSize), + MemoryEventFactory( + sessionType = sessionType, + totalRamBytes = totalRamBytes, + timeProvider = timeProvider, + batteryInfoProvider = FixedInfoProvider(batteryInfo), + displayInfoProvider = FixedInfoProvider(displayInfo), + internalLogger = internalLogger + ) + ), + Triple( + CSVReader(csvContent, METRIC_CPU_USAGE, timeProvider), + Buffer(bufferSize), + CpuEventFactory( + sessionType = sessionType, + timeProvider = timeProvider, + batteryInfoProvider = FixedInfoProvider(batteryInfo), + displayInfoProvider = FixedInfoProvider(displayInfo), + internalLogger = internalLogger + ) ) ) ) - ) + } + + private class FixedInfoProvider(private val state: T) : InfoProvider { + override fun getState(): T = state + override fun cleanup() = Unit + } const val METRIC_MEMORY_USAGE: String = "memory_usage" const val METRIC_CPU_USAGE: String = "cpu_usage" + + private val CUSTOM_ATTRIBUTES = mapOf("fake-attribute-key" to "fake-attribute-value") } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt index a99daaf644..28f37cfdd2 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt @@ -6,21 +6,17 @@ package com.datadog.android.rum.internal.timeseries.csv -import com.datadog.android.api.context.DatadogContext import com.datadog.android.internal.time.TimeProvider import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.timeseries.serializer.TimeseriesAttributes +import com.datadog.android.rum.assertj.TimeseriesCpuEventAssert +import com.datadog.android.rum.assertj.TimeseriesMemoryEventAssert +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent import com.datadog.android.rum.utils.forge.Configurator -import com.google.gson.JsonArray -import com.google.gson.JsonElement -import com.google.gson.JsonNull -import com.google.gson.JsonObject -import com.google.gson.JsonParser -import com.google.gson.JsonPrimitive +import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.Assertions.fail import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -29,10 +25,9 @@ import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock import org.mockito.kotlin.whenever import org.mockito.quality.Strictness -import java.math.BigDecimal -import java.util.UUID @Extensions( ExtendWith(MockitoExtension::class), @@ -45,208 +40,118 @@ internal class TimeseriesCollectorEndToEndTest { @Mock lateinit var mockTimeProvider: TimeProvider - @Mock - lateinit var mockDatadogContext: DatadogContext - - private lateinit var csvContent: String - private lateinit var emitted: List + private lateinit var capturedMemoryEvents: List + private lateinit var capturedCpuEvents: List @BeforeEach - fun `set up`() { - whenever(mockTimeProvider.getDeviceTimestampMillis()) doReturn FIXED_DATE_MS + fun `set up`(forge: Forge) { + whenever(mockTimeProvider.getServerTimestampMillis()) doReturn FIXED_DATE_MS - csvContent = loadResource("fixtures/timeseries/input_memory_cpu.csv") val testedTimeseries = CsvCollector.create( - csvContent = csvContent, - sessionId = SESSION_ID, - applicationId = APPLICATION_ID, + csvContent = loadResource("fixtures/timeseries/input_memory_cpu.csv"), sessionType = RumSessionType.USER, totalRamBytes = TOTAL_RAM_BYTES, bufferSize = BATCH_SIZE, timeProvider = mockTimeProvider, - datadogContext = mockDatadogContext + forge = forge, + internalLogger = mock() ) testedTimeseries.onSessionStart() - testedTimeseries.onSessionStop() - emitted = testedTimeseries.captured + capturedMemoryEvents = testedTimeseries.captured.mapNotNull { serializedPayload -> + runCatching { TimeseriesMemoryEvent.fromJsonObject(serializedPayload) } + .getOrNull() + } + capturedCpuEvents = testedTimeseries.captured.mapNotNull { serializedPayload -> + runCatching { TimeseriesCpuEvent.fromJsonObject(serializedPayload) } + .getOrNull() + } } @Test fun `M emit two memory and two cpu batches W full CSV is fed { batchSize=5, samples=10 }`() { // Then - val memoryEvents = emitted.filter { metricNameOf(it) == NAME_MEMORY } - val cpuEvents = emitted.filter { metricNameOf(it) == NAME_CPU } - - assertThat(memoryEvents).hasSize(2) - assertThat(cpuEvents).hasSize(2) + assertThat(capturedMemoryEvents.size).isEqualTo(2) + assertThat(capturedCpuEvents.size).isEqualTo(2) } @Test - fun `M match expected fixture W memory batch 1`() { - val expected = loadFixture("fixtures/timeseries/expected_memory_batch1.json") - val actual = emitted.filter { metricNameOf(it) == NAME_MEMORY }[0] - assertJsonEquals(expected, maskTimeseriesId(actual)) + fun `M match expected timeseries fixture W memory batch 1`() { + val expected = loadExpectedMemoryTimeseries("fixtures/timeseries/expected_memory_batch1.json") + val actual = capturedMemoryEvents[0] + + TimeseriesMemoryEventAssert.assertThat(actual) + .hasDate(expected.date) + .hasSameTimeseriesAs(expected) } @Test - fun `M match expected fixture W memory batch 2`() { - val expected = loadFixture("fixtures/timeseries/expected_memory_batch2.json") - val actual = emitted.filter { metricNameOf(it) == NAME_MEMORY }[1] - assertJsonEquals(expected, maskTimeseriesId(actual)) + fun `M match expected timeseries fixture W memory batch 2`() { + val expected = loadExpectedMemoryTimeseries("fixtures/timeseries/expected_memory_batch2.json") + val actual = capturedMemoryEvents[1] + + TimeseriesMemoryEventAssert.assertThat(actual) + .hasDate(expected.date) + .hasSameTimeseriesAs(expected) } @Test - fun `M match expected fixture W cpu batch 1`() { - val expected = loadFixture("fixtures/timeseries/expected_cpu_batch1.json") - val actual = emitted.filter { metricNameOf(it) == NAME_CPU }[0] - assertJsonEquals(expected, maskTimeseriesId(actual)) + fun `M match expected timeseries fixture W cpu batch 1`() { + val expected = loadExpectedCpuTimeseries("fixtures/timeseries/expected_cpu_batch1.json") + val actual = capturedCpuEvents[0] + + TimeseriesCpuEventAssert.assertThat(actual) + .hasDate(expected.date) + .hasSameTimeseriesAs(expected) } @Test - fun `M match expected fixture W cpu batch 2`() { - val expected = loadFixture("fixtures/timeseries/expected_cpu_batch2.json") - val actual = emitted.filter { metricNameOf(it) == NAME_CPU }[1] - assertJsonEquals(expected, maskTimeseriesId(actual)) + fun `M match expected timeseries fixture W cpu batch 2`() { + val expected = loadExpectedCpuTimeseries("fixtures/timeseries/expected_cpu_batch2.json") + val actual = capturedCpuEvents[1] + + TimeseriesCpuEventAssert.assertThat(actual) + .hasDate(expected.date) + .hasSameTimeseriesAs(expected) } @Test fun `M emit valid timeseries id W any batch`() { - // Each emitted event must carry a non-blank UUID; randomness is not asserted. - for (event in emitted) { - val id = event.getAsJsonObject(TimeseriesAttributes.KEY_TIMESERIES).get("id").asString - assertThat(UUID.fromString(id)).isNotNull + capturedMemoryEvents.forEach { actual -> + TimeseriesMemoryEventAssert.assertThat(actual) + .hasValidTimeseriesId() + } + capturedCpuEvents.forEach { actual -> + TimeseriesCpuEventAssert.assertThat(actual) + .hasValidTimeseriesId() } } @Test fun `M produce monotonic start lt or eq to end W any batch`() { - for (event in emitted) { - val ts = event.getAsJsonObject(TimeseriesAttributes.KEY_TIMESERIES) - assertThat(ts.get("start").asLong).isLessThanOrEqualTo(ts.get("end").asLong) - } - } - - private fun metricNameOf(event: JsonObject): String = - event.getAsJsonObject(TimeseriesAttributes.KEY_TIMESERIES) - .get(TimeseriesAttributes.KEY_NAME) - .asString - - private fun maskTimeseriesId(actual: JsonObject): JsonObject { - val copy = actual.deepCopy() - copy.getAsJsonObject(TimeseriesAttributes.KEY_TIMESERIES) - .addProperty(KEY_ID, MASKED_UUID) - return copy - } - - private fun loadFixture(path: String): JsonElement = JsonParser.parseString(loadResource(path)) - - private fun loadResource(path: String): String { - val stream = this::class.java.classLoader?.getResourceAsStream(path) - ?: error("Resource not found: $path") - return stream.bufferedReader().use { it.readText() } - } - - /** - * Structural JSON comparison that ignores key insertion order and treats numerically - * equal primitives as equal regardless of literal representation - * (e.g. `31233300` vs `3.12333E7`). - */ - private fun assertJsonEquals(expected: JsonElement, actual: JsonElement, path: String = "$") { - when { - expected is JsonObject && actual is JsonObject -> { - val expectedKeys: Set = expected.keySet() - val actualKeys: Set = actual.keySet() - assertThat(actualKeys.toList()) - .describedAs("Keys at %s", path) - .containsExactlyInAnyOrderElementsOf(expectedKeys.toList()) - for (key in expectedKeys) { - assertJsonEquals(expected.get(key), actual.get(key), "$path.$key") - } - } - expected is JsonArray && actual is JsonArray -> { - assertThat(actual.size()) - .describedAs("Array size at %s", path) - .isEqualTo(expected.size()) - for (i in 0 until expected.size()) { - assertJsonEquals(expected.get(i), actual.get(i), "$path[$i]") - } - } - expected is JsonPrimitive && actual is JsonPrimitive -> { - assertPrimitiveEquals(expected, actual, path) - } - expected is JsonNull && actual is JsonNull -> Unit - else -> assertThat(actual) - .describedAs("Type mismatch at %s", path) - .isEqualTo(expected) - } - } - - private fun assertPrimitiveEquals(expected: JsonPrimitive, actual: JsonPrimitive, path: String) { - when { - expected.isString != actual.isString -> - fail( - "JSON type mismatch at $path: expected ${if (expected.isString) "string" else "number/boolean"}," + - " got ${if (actual.isString) "string" else "number/boolean"}" + - " (values: ${expected.asString} vs ${actual.asString})" - ) - expected.isBoolean != actual.isBoolean -> - fail( - "JSON type mismatch at $path: expected ${if (expected.isBoolean) "boolean" else "non-boolean"}," + - " got ${if (actual.isBoolean) "boolean" else "non-boolean"}" + - " (values: ${expected.asString} vs ${actual.asString})" - ) - expected.isString -> - assertThat(actual.asString).describedAs("String at %s", path).isEqualTo(expected.asString) - expected.isBoolean -> - assertThat(actual.asBoolean).describedAs("Boolean at %s", path).isEqualTo(expected.asBoolean) - else -> assertNumericPrimitivesEqual(expected, actual, path) + capturedMemoryEvents.forEach { actual -> + TimeseriesMemoryEventAssert.assertThat(actual) + .hasTimeseriesStartNotAfterEnd() } - } - - // Numeric: integer-typed values must match exactly; floating-point values are compared - // with a small relative tolerance to absorb 64-bit FP rounding (e.g. computed - // memory_percent of 3.1233299999999997 vs expected 3.12333). - private fun assertNumericPrimitivesEqual(expected: JsonPrimitive, actual: JsonPrimitive, path: String) { - val expectedBd = expected.asString.toBigDecimalOrNull() - ?: error("Expected numeric value at $path, got: ${expected.asString}") - val actualBd = actual.asString.toBigDecimalOrNull() - ?: error("Actual numeric value at $path is not a number: ${actual.asString}") - - val isFloat = expected.asString.contains('.') || - expected.asString.contains('e', ignoreCase = true) || - actual.asString.contains('.') || - actual.asString.contains('e', ignoreCase = true) - - if (isFloat) { - val expectedDouble = expectedBd.toDouble() - val actualDouble = actualBd.toDouble() - assertThat(actualDouble) - .describedAs("Double at %s: expected=%s, actual=%s", path, expectedDouble, actualDouble) - .isCloseTo(expectedDouble, org.assertj.core.data.Offset.offset(FP_TOLERANCE)) - } else { - assertThat(actualBd.compareTo(expectedBd)) - .describedAs("Integer at %s: expected=%s, actual=%s", path, expectedBd, actualBd) - .isZero + capturedCpuEvents.forEach { actual -> + TimeseriesCpuEventAssert.assertThat(actual) + .hasTimeseriesStartNotAfterEnd() } } - private fun String.toBigDecimalOrNull(): BigDecimal? = try { - BigDecimal(this) - } catch (_: NumberFormatException) { - null - } - - companion object { - private const val SESSION_ID: String = "fake-session-id" - private const val APPLICATION_ID: String = "fake-app-id" + private companion object { private const val FIXED_DATE_MS: Long = 1_700_000_001_000L private const val TOTAL_RAM_BYTES: Long = 1_000_000_000L private const val BATCH_SIZE: Int = 5 - private const val NAME_MEMORY: String = "memory" - private const val NAME_CPU: String = "cpu" - private const val MASKED_UUID: String = "00000000-0000-0000-0000-000000000000" - private const val FP_TOLERANCE: Double = 1e-9 + private fun loadExpectedMemoryTimeseries(path: String): TimeseriesMemoryEvent = + TimeseriesMemoryEvent.fromJson(loadResource(path)) + + private fun loadExpectedCpuTimeseries(path: String): TimeseriesCpuEvent = + TimeseriesCpuEvent.fromJson(loadResource(path)) - private const val KEY_ID: String = "id" + private fun loadResource(path: String): String { + val stream = this::class.java.classLoader?.getResourceAsStream(path) + ?: error("Resource not found: $path") + return stream.bufferedReader().use { it.readText() } + } } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactoryTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactoryTest.kt new file mode 100644 index 0000000000..ff4fc622e6 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/CpuEventFactoryTest.kt @@ -0,0 +1,469 @@ +/* + * 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.rum.internal.timeseries.factory + +import com.datadog.android.api.InternalLogger +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.api.feature.Feature +import com.datadog.android.core.internal.utils.DdTagsUtils +import com.datadog.android.internal.time.TimeProvider +import com.datadog.android.rum.RumSessionType +import com.datadog.android.rum.assertj.TimeseriesCpuEventAssert +import com.datadog.android.rum.internal.FeaturesContextResolver +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.domain.scope.RumSessionScope +import com.datadog.android.rum.internal.domain.scope.RumViewScope +import com.datadog.android.rum.internal.domain.scope.toTimeseriesCpuSchemaType +import com.datadog.android.rum.internal.timeseries.DataPoint +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent.TimeseriesCpuEventSessionType +import com.datadog.android.rum.utils.forge.Configurator +import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.annotation.BoolForgery +import fr.xgouchet.elmyr.annotation.DoubleForgery +import fr.xgouchet.elmyr.annotation.FloatForgery +import fr.xgouchet.elmyr.annotation.Forgery +import fr.xgouchet.elmyr.annotation.LongForgery +import fr.xgouchet.elmyr.annotation.StringForgery +import fr.xgouchet.elmyr.junit5.ForgeConfiguration +import fr.xgouchet.elmyr.junit5.ForgeExtension +import org.assertj.core.api.Assertions.assertThat +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.Arguments +import org.junit.jupiter.params.provider.MethodSource +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(Configurator::class) +internal class CpuEventFactoryTest { + + @Mock + lateinit var mockTimeProvider: TimeProvider + + @Mock + lateinit var mockInternalLogger: InternalLogger + + @Mock + lateinit var stubBatteryInfoProvider: InfoProvider + + @Mock + lateinit var stubDisplayInfoProvider: InfoProvider + + @StringForgery + lateinit var fakeSessionId: String + + @StringForgery + lateinit var fakeApplicationId: String + + @LongForgery(min = 1L) + var fakeNowMs: Long = 0L + + @FloatForgery(min = 0f, max = 1f) + var fakeBatteryLevel: Float = 0f + + @BoolForgery + var fakeLowPowerMode: Boolean = false + + @FloatForgery(min = 0f, max = 1f) + var fakeBrightnessLevel: Float = 0f + + @Forgery + lateinit var fakeDatadogContext: DatadogContext + + private var fakeSource: TimeseriesCpuEvent.Source? = null + + @Forgery + lateinit var fakeRumContext: RumContext + + private val fakeSerializedRumContext: RumContext + get() = fakeRumContext.copy(applicationId = fakeApplicationId, sessionId = fakeSessionId) + + private val oneSample = listOf(DataPoint(1L, 1.0)) + + @BeforeEach + fun `set up`(forge: Forge) { + fakeSource = forge.aNullable { aValueFrom(TimeseriesCpuEvent.Source::class.java) } + fakeDatadogContext = fakeDatadogContext.copy( + source = fakeSource?.toJson()?.asString ?: forge.anAlphabeticalString() + ) + whenever(mockTimeProvider.getServerTimestampMillis()) doReturn fakeNowMs + whenever(stubBatteryInfoProvider.getState()) doReturn BatteryInfo( + batteryLevel = fakeBatteryLevel, + lowPowerMode = fakeLowPowerMode + ) + whenever(stubDisplayInfoProvider.getState()) doReturn DisplayInfo(screenBrightness = fakeBrightnessLevel) + } + + private fun testedFactory( + sessionType: RumSessionType = RumSessionType.USER + ) = CpuEventFactory( + sessionType = sessionType, + timeProvider = mockTimeProvider, + batteryInfoProvider = stubBatteryInfoProvider, + displayInfoProvider = stubDisplayInfoProvider, + internalLogger = mockInternalLogger + ) + + @Test + fun `M return null W create() { empty input }`() { + // When + val result = testedFactory().create(fakeDatadogContext, fakeSerializedRumContext, emptyList(), emptyMap()) + + // Then + assertThat(result).isNull() + } + + @Test + fun `M fill timeseries W create() { multiple data points }`( + @DoubleForgery(min = 0.0, max = 100.0) fakeCpuValue: Double, + @LongForgery(min = 1L) fakeTs: Long + ) { + // Given + val samples = listOf( + DataPoint(fakeTs, fakeCpuValue), + DataPoint(fakeTs + 1L, fakeCpuValue + 0.1) + ) + + // When + val event = createSerializedEvent(dataPoints = samples) + + // Then + TimeseriesCpuEventAssert.assertThat(event) + .hasTimeseriesName(VALUE_NAME_CPU) + .hasTimeseriesSchema(VALUE_SCHEMA_OBJECT) + .hasDate(fakeNowMs) + .hasValidTimeseriesId() + .hasDataPointsCount(2) + .hasTimeseriesStart(fakeTs) + .hasTimeseriesEnd(fakeTs + 1L) + .hasApplicationId(fakeApplicationId) + .hasSessionId(fakeSessionId) + .hasSessionType(TimeseriesCpuEventSessionType.USER) + .hasService(fakeDatadogContext.service) + .hasVersion(fakeDatadogContext.version) + } + + @Test + fun `M map session type W create() { synthetics }`() { + // When + val event = createEvent(sessionType = RumSessionType.SYNTHETICS) + + // Then + TimeseriesCpuEventAssert.assertThat(event).hasSessionType(TimeseriesCpuEventSessionType.SYNTHETICS) + } + + @Test + fun `M return generated timeseries name W eventName`() { + // When / Then + assertThat(testedFactory().eventName).isEqualTo(createEvent().timeseries.name) + } + + @Test + fun `M fill cpu_usage W create() { one value per data point }`( + @DoubleForgery(min = 1.0, max = 100.0) fakeFirstCpu: Double, + @DoubleForgery(min = 1.0, max = 100.0) fakeSecondCpu: Double, + @LongForgery(min = 1L) fakeTs: Long + ) { + // Given + val samples = listOf( + DataPoint(fakeTs, fakeFirstCpu), + DataPoint(fakeTs + 1L, fakeSecondCpu) + ) + + // When + val event = createSerializedEvent(dataPoints = samples) + + // Then + TimeseriesCpuEventAssert.assertThat(event) + .hasDataPointsCount(2) + .hasCpuUsage(fakeFirstCpu, position = 0) + .hasCpuUsage(fakeSecondCpu, position = 1) + .hasTimestamps(fakeTs, fakeTs + 1L) + } + + @Test + fun `M fill application and build info W create()`( + @StringForgery fakeBuildId: String + ) { + // Given + val datadogContext = fakeDatadogContext.copy(appBuildId = fakeBuildId) + + // When + val event = createEvent(datadogContext = datadogContext) + + // Then + assertThat(event.application.id).isEqualTo(fakeApplicationId) + assertThat(event.application.currentLocale) + .isEqualTo(datadogContext.deviceInfo.localeInfo.currentLocale) + assertThat(event.source).isEqualTo(fakeSource) + assertThat(event.buildVersion).isEqualTo(datadogContext.versionCode.toString()) + assertThat(event.buildId).isEqualTo(fakeBuildId) + assertThat(event.ddtags).isEqualTo(DdTagsUtils.toDdTagsString(datadogContext)) + } + + @Test + fun `M fill os and device W create()`() { + // Given + val deviceInfo = fakeDatadogContext.deviceInfo + + // When + val event = createEvent() + + // Then + val os = checkNotNull(event.os) + assertThat(os.name).isEqualTo(deviceInfo.osName) + assertThat(os.version).isEqualTo(deviceInfo.osVersion) + assertThat(os.versionMajor).isEqualTo(deviceInfo.osMajorVersion) + + val device = checkNotNull(event.device) + assertThat(device.type).isEqualTo(deviceInfo.deviceType.toTimeseriesCpuSchemaType()) + assertThat(device.name).isEqualTo(deviceInfo.deviceName) + assertThat(device.model).isEqualTo(deviceInfo.deviceModel) + assertThat(device.brand).isEqualTo(deviceInfo.deviceBrand) + assertThat(device.architecture).isEqualTo(deviceInfo.architecture) + assertThat(device.locales).isEqualTo(deviceInfo.localeInfo.locales) + assertThat(device.timeZone).isEqualTo(deviceInfo.localeInfo.timeZone) + assertThat(device.logicalCpuCount?.toInt()).isEqualTo(deviceInfo.logicalCpuCount) + assertThat(device.totalRam?.toInt()).isEqualTo(deviceInfo.totalRam) + assertThat(device.isLowRam).isEqualTo(deviceInfo.isLowRam) + assertThat(device.batteryLevel?.toFloat()).isEqualTo(fakeBatteryLevel) + assertThat(device.powerSavingMode).isEqualTo(fakeLowPowerMode) + assertThat(device.brightnessLevel?.toFloat()).isEqualTo(fakeBrightnessLevel) + } + + @Test + fun `M leave device power info null W create() { providers have no data }`() { + // Given + whenever(stubBatteryInfoProvider.getState()) doReturn BatteryInfo() + whenever(stubDisplayInfoProvider.getState()) doReturn DisplayInfo() + + // When + val event = createEvent() + + // Then + val device = checkNotNull(event.device) + assertThat(device.batteryLevel).isNull() + assertThat(device.powerSavingMode).isNull() + assertThat(device.brightnessLevel).isNull() + } + + @Test + fun `M fill dd W create()`( + @DoubleForgery(min = 0.0, max = 100.0) fakeSampleRate: Double + ) { + // Given + val rumContext = fakeSerializedRumContext.copy( + sessionStartReason = RumSessionScope.StartReason.INACTIVITY_TIMEOUT, + sessionSampleRate = fakeSampleRate.toFloat() + ) + + // When + val event = createEvent(rumContext = rumContext) + + // Then + assertThat(event.dd.session?.sessionPrecondition) + .isEqualTo(TimeseriesCpuEvent.SessionPrecondition.INACTIVITY_TIMEOUT) + assertThat(event.dd.configuration?.sessionSampleRate?.toFloat()) + .isEqualTo(fakeSampleRate.toFloat()) + } + + @Test + fun `M fill dd configuration W create() { sample rates in features context }`( + @LongForgery(min = 0L, max = 100L) fakeSessionReplaySampleRate: Long, + @FloatForgery(min = 0f, max = 100f) fakeTraceSampleRate: Float + ) { + // Given + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to mapOf( + RumViewScope.SESSION_REPLAY_SAMPLE_RATE_KEY to fakeSessionReplaySampleRate + ), + Feature.TRACING_FEATURE_NAME to mapOf( + RumViewScope.TRACE_SAMPLE_RATE to fakeTraceSampleRate + ) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext) + + // Then + val configuration = checkNotNull(event.dd.configuration) + assertThat(configuration.sessionReplaySampleRate?.toLong()).isEqualTo(fakeSessionReplaySampleRate) + assertThat(configuration.traceSampleRate?.toFloat()).isEqualTo(fakeTraceSampleRate) + } + + @Test + fun `M fill dd configuration W create() { sample rates missing or of wrong type }`( + @StringForgery fakeNotASampleRate: String + ) { + // Given + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to emptyMap(), + Feature.TRACING_FEATURE_NAME to mapOf(RumViewScope.TRACE_SAMPLE_RATE to fakeNotASampleRate) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext) + + // Then + val configuration = checkNotNull(event.dd.configuration) + assertThat(configuration.sessionReplaySampleRate).isNull() + assertThat(configuration.traceSampleRate).isNull() + } + + @Test + fun `M fill session hasReplay W create() { view is recorded }`( + @StringForgery fakeViewId: String + ) { + // Given + val rumContext = fakeSerializedRumContext.copy(viewId = fakeViewId) + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to mapOf( + fakeViewId to mapOf(FeaturesContextResolver.HAS_REPLAY_KEY to true) + ) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext, rumContext = rumContext) + + // Then + assertThat(event.session.hasReplay).isTrue() + } + + @Test + fun `M fill session hasReplay W create() { view is not recorded }`( + @StringForgery fakeViewId: String + ) { + // Given + val rumContext = fakeSerializedRumContext.copy(viewId = fakeViewId) + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to mapOf( + fakeViewId to mapOf(FeaturesContextResolver.HAS_REPLAY_KEY to false) + ) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext, rumContext = rumContext) + + // Then + assertThat(event.session.hasReplay).isFalse() + } + + @Test + fun `M fill synthetics W create() { synthetics ids are set }`( + @StringForgery fakeTestId: String, + @StringForgery fakeResultId: String + ) { + // Given + val rumContext = fakeSerializedRumContext.copy( + syntheticsTestId = fakeTestId, + syntheticsResultId = fakeResultId + ) + + // When + val event = createEvent(rumContext = rumContext) + + // Then + assertThat(event.synthetics?.testId).isEqualTo(fakeTestId) + assertThat(event.synthetics?.resultId).isEqualTo(fakeResultId) + } + + @ParameterizedTest + @MethodSource("incompleteSyntheticsIds") + fun `M not fill synthetics W create() { synthetics ids are incomplete }`( + syntheticsTestId: String?, + syntheticsResultId: String? + ) { + // Given + val rumContext = fakeSerializedRumContext.copy( + syntheticsTestId = syntheticsTestId, + syntheticsResultId = syntheticsResultId + ) + + // When + val event = createEvent(rumContext = rumContext) + + // Then + assertThat(event.synthetics).isNull() + } + + @Test + fun `M leave unsupported fields null W create()`() { + // When + val event = createEvent() + + // Then + assertThat(event.connectivity).isNull() + assertThat(event.usr).isNull() + assertThat(event.account).isNull() + assertThat(event.context).isNull() + assertThat(event.view).isNull() + assertThat(event.ciTest).isNull() + assertThat(event.display).isNull() + } + + private fun createSerializedEvent( + datadogContext: DatadogContext = fakeDatadogContext, + rumContext: RumContext = fakeSerializedRumContext, + sessionType: RumSessionType = RumSessionType.USER, + dataPoints: List> = oneSample + ): TimeseriesCpuEvent = TimeseriesCpuEvent.fromJson( + checkNotNull( + testedFactory(sessionType = sessionType) + .create(datadogContext, rumContext, dataPoints, emptyMap()) + ).toJson().toString() + ) + + private fun createEvent( + datadogContext: DatadogContext = fakeDatadogContext, + rumContext: RumContext = fakeSerializedRumContext, + sessionType: RumSessionType = RumSessionType.USER + ): TimeseriesCpuEvent = checkNotNull( + testedFactory(sessionType = sessionType) + .create(datadogContext, rumContext, oneSample, emptyMap()) + ) + + companion object { + private const val VALUE_NAME_CPU: String = "cpu" + private const val VALUE_SCHEMA_OBJECT: String = "object-v2" + + private const val FAKE_SYNTHETICS_ID: String = "synthetics-id" + + @JvmStatic + fun incompleteSyntheticsIds(): List = listOf( + Arguments.of(null, null), + Arguments.of("", " "), + Arguments.of(FAKE_SYNTHETICS_ID, null), + Arguments.of(null, FAKE_SYNTHETICS_ID), + Arguments.of(FAKE_SYNTHETICS_ID, " "), + Arguments.of("", FAKE_SYNTHETICS_ID) + ) + } +} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactoryTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactoryTest.kt new file mode 100644 index 0000000000..a9afec6e06 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/factory/MemoryEventFactoryTest.kt @@ -0,0 +1,501 @@ +/* + * 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.rum.internal.timeseries.factory + +import com.datadog.android.api.InternalLogger +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.api.feature.Feature +import com.datadog.android.core.internal.utils.DdTagsUtils +import com.datadog.android.internal.time.TimeProvider +import com.datadog.android.rum.RumSessionType +import com.datadog.android.rum.assertj.TimeseriesMemoryEventAssert +import com.datadog.android.rum.internal.FeaturesContextResolver +import com.datadog.android.rum.internal.domain.InfoProvider +import com.datadog.android.rum.internal.domain.RumContext +import com.datadog.android.rum.internal.domain.battery.BatteryInfo +import com.datadog.android.rum.internal.domain.display.DisplayInfo +import com.datadog.android.rum.internal.domain.scope.RumSessionScope +import com.datadog.android.rum.internal.domain.scope.RumViewScope +import com.datadog.android.rum.internal.domain.scope.toTimeseriesMemorySchemaType +import com.datadog.android.rum.internal.timeseries.DataPoint +import com.datadog.android.rum.model.TimeseriesMemoryEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent.TimeseriesMemoryEventSessionType +import com.datadog.android.rum.utils.forge.Configurator +import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.annotation.BoolForgery +import fr.xgouchet.elmyr.annotation.DoubleForgery +import fr.xgouchet.elmyr.annotation.FloatForgery +import fr.xgouchet.elmyr.annotation.Forgery +import fr.xgouchet.elmyr.annotation.LongForgery +import fr.xgouchet.elmyr.annotation.StringForgery +import fr.xgouchet.elmyr.junit5.ForgeConfiguration +import fr.xgouchet.elmyr.junit5.ForgeExtension +import org.assertj.core.api.Assertions.assertThat +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.Arguments +import org.junit.jupiter.params.provider.MethodSource +import org.junit.jupiter.params.provider.ValueSource +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(Configurator::class) +internal class MemoryEventFactoryTest { + + @Mock + lateinit var mockTimeProvider: TimeProvider + + @Mock + lateinit var mockInternalLogger: InternalLogger + + @Mock + lateinit var stubBatteryInfoProvider: InfoProvider + + @Mock + lateinit var stubDisplayInfoProvider: InfoProvider + + @StringForgery + lateinit var fakeSessionId: String + + @StringForgery + lateinit var fakeApplicationId: String + + @LongForgery(min = 1_000_000_000L, max = 16_000_000_000L) + var fakeTotalRamBytes: Long = 0L + + @LongForgery(min = 1L) + var fakeNowMs: Long = 0L + + @FloatForgery(min = 0f, max = 1f) + var fakeBatteryLevel: Float = 0f + + @BoolForgery + var fakeLowPowerMode: Boolean = false + + @FloatForgery(min = 0f, max = 1f) + var fakeBrightnessLevel: Float = 0f + + @Forgery + lateinit var fakeDatadogContext: DatadogContext + + private var fakeSource: TimeseriesMemoryEvent.Source? = null + + @Forgery + lateinit var fakeRumContext: RumContext + + private val fakeSerializedRumContext: RumContext + get() = fakeRumContext.copy(applicationId = fakeApplicationId, sessionId = fakeSessionId) + + private val oneSample = listOf(DataPoint(1L, 1.0)) + + @BeforeEach + fun `set up`(forge: Forge) { + fakeSource = forge.aNullable { aValueFrom(TimeseriesMemoryEvent.Source::class.java) } + fakeDatadogContext = fakeDatadogContext.copy( + source = fakeSource?.toJson()?.asString ?: forge.anAlphabeticalString() + ) + whenever(mockTimeProvider.getServerTimestampMillis()) doReturn fakeNowMs + whenever(stubBatteryInfoProvider.getState()) doReturn BatteryInfo( + batteryLevel = fakeBatteryLevel, + lowPowerMode = fakeLowPowerMode + ) + whenever(stubDisplayInfoProvider.getState()) doReturn DisplayInfo(screenBrightness = fakeBrightnessLevel) + } + + private fun testedFactory( + sessionType: RumSessionType = RumSessionType.USER, + totalRamBytes: Long = fakeTotalRamBytes + ) = MemoryEventFactory( + sessionType = sessionType, + totalRamBytes = totalRamBytes, + timeProvider = mockTimeProvider, + batteryInfoProvider = stubBatteryInfoProvider, + displayInfoProvider = stubDisplayInfoProvider, + internalLogger = mockInternalLogger + ) + + @Test + fun `M return null W create() { empty input }`() { + // When + val result = testedFactory().create(fakeDatadogContext, fakeSerializedRumContext, emptyList(), emptyMap()) + + // Then + assertThat(result).isNull() + } + + @ParameterizedTest + @ValueSource(longs = [0L, -1L, Long.MIN_VALUE]) + fun `M return null W create() { totalRamBytes is not positive }`(totalRamBytes: Long) { + // When + val result = testedFactory(totalRamBytes = totalRamBytes) + .create(fakeDatadogContext, fakeSerializedRumContext, oneSample, emptyMap()) + + // Then + assertThat(result).isNull() + } + + @Test + fun `M fill timeseries W create() { multiple data points }`( + @DoubleForgery(min = 1.0) fakeMemory: Double, + @LongForgery(min = 1L) fakeTs: Long + ) { + // Given + val samples = listOf( + DataPoint(fakeTs, fakeMemory), + DataPoint(fakeTs + 1L, fakeMemory + 1.0) + ) + + // When + val event = createSerializedEvent(dataPoints = samples) + + // Then + TimeseriesMemoryEventAssert.assertThat(event) + .hasTimeseriesName(VALUE_NAME_MEMORY) + .hasTimeseriesSchema(VALUE_SCHEMA_OBJECT) + .hasDate(fakeNowMs) + .hasValidTimeseriesId() + .hasDataPointsCount(2) + .hasTimeseriesStart(fakeTs) + .hasTimeseriesEnd(fakeTs + 1L) + .hasApplicationId(fakeApplicationId) + .hasSessionId(fakeSessionId) + .hasSessionType(TimeseriesMemoryEventSessionType.USER) + .hasService(fakeDatadogContext.service) + .hasVersion(fakeDatadogContext.version) + } + + @Test + fun `M map session type W create() { synthetics }`() { + // When + val event = createEvent(sessionType = RumSessionType.SYNTHETICS) + + // Then + TimeseriesMemoryEventAssert.assertThat(event) + .hasSessionType(TimeseriesMemoryEventSessionType.SYNTHETICS) + } + + @Test + fun `M return generated timeseries name W eventName`() { + // When / Then + assertThat(testedFactory().eventName).isEqualTo(createEvent().timeseries.name) + } + + @Test + fun `M fill memory values W create() { one value per data point }`( + @DoubleForgery(min = 1.0, max = 16_000_000_000.0) fakeFirstMemory: Double, + @DoubleForgery(min = 1.0, max = 16_000_000_000.0) fakeSecondMemory: Double, + @LongForgery(min = 1L) fakeTs: Long + ) { + // Given + val samples = listOf( + DataPoint(fakeTs, fakeFirstMemory), + DataPoint(fakeTs + 1L, fakeSecondMemory) + ) + + // When + val event = createSerializedEvent(dataPoints = samples) + + // Then + TimeseriesMemoryEventAssert.assertThat(event) + .hasDataPointsCount(2) + .hasMemoryFootprint(fakeFirstMemory / BYTES_IN_KB, MEMORY_OFFSET, position = 0) + .hasMemoryFootprint(fakeSecondMemory / BYTES_IN_KB, MEMORY_OFFSET, position = 1) + .hasMemoryPercent( + fakeFirstMemory / fakeTotalRamBytes * PERCENT_FACTOR, + MEMORY_OFFSET, + position = 0 + ) + .hasMemoryPercent( + fakeSecondMemory / fakeTotalRamBytes * PERCENT_FACTOR, + MEMORY_OFFSET, + position = 1 + ) + .hasTimestamps(fakeTs, fakeTs + 1L) + } + + @Test + fun `M fill application and build info W create()`( + @StringForgery fakeBuildId: String + ) { + // Given + val datadogContext = fakeDatadogContext.copy(appBuildId = fakeBuildId) + + // When + val event = createEvent(datadogContext = datadogContext) + + // Then + assertThat(event.application.id).isEqualTo(fakeApplicationId) + assertThat(event.application.currentLocale) + .isEqualTo(datadogContext.deviceInfo.localeInfo.currentLocale) + assertThat(event.source).isEqualTo(fakeSource) + assertThat(event.buildVersion).isEqualTo(datadogContext.versionCode.toString()) + assertThat(event.buildId).isEqualTo(fakeBuildId) + assertThat(event.ddtags).isEqualTo(DdTagsUtils.toDdTagsString(datadogContext)) + } + + @Test + fun `M fill os and device W create()`() { + // Given + val deviceInfo = fakeDatadogContext.deviceInfo + + // When + val event = createEvent() + + // Then + val os = checkNotNull(event.os) + assertThat(os.name).isEqualTo(deviceInfo.osName) + assertThat(os.version).isEqualTo(deviceInfo.osVersion) + assertThat(os.versionMajor).isEqualTo(deviceInfo.osMajorVersion) + + val device = checkNotNull(event.device) + assertThat(device.type).isEqualTo(deviceInfo.deviceType.toTimeseriesMemorySchemaType()) + assertThat(device.name).isEqualTo(deviceInfo.deviceName) + assertThat(device.model).isEqualTo(deviceInfo.deviceModel) + assertThat(device.brand).isEqualTo(deviceInfo.deviceBrand) + assertThat(device.architecture).isEqualTo(deviceInfo.architecture) + assertThat(device.locales).isEqualTo(deviceInfo.localeInfo.locales) + assertThat(device.timeZone).isEqualTo(deviceInfo.localeInfo.timeZone) + assertThat(device.logicalCpuCount?.toInt()).isEqualTo(deviceInfo.logicalCpuCount) + assertThat(device.totalRam?.toInt()).isEqualTo(deviceInfo.totalRam) + assertThat(device.isLowRam).isEqualTo(deviceInfo.isLowRam) + assertThat(device.batteryLevel?.toFloat()).isEqualTo(fakeBatteryLevel) + assertThat(device.powerSavingMode).isEqualTo(fakeLowPowerMode) + assertThat(device.brightnessLevel?.toFloat()).isEqualTo(fakeBrightnessLevel) + } + + @Test + fun `M leave device power info null W create() { providers have no data }`() { + // Given + whenever(stubBatteryInfoProvider.getState()) doReturn BatteryInfo() + whenever(stubDisplayInfoProvider.getState()) doReturn DisplayInfo() + + // When + val event = createEvent() + + // Then + val device = checkNotNull(event.device) + assertThat(device.batteryLevel).isNull() + assertThat(device.powerSavingMode).isNull() + assertThat(device.brightnessLevel).isNull() + } + + @Test + fun `M fill dd W create()`( + @DoubleForgery(min = 0.0, max = 100.0) fakeSampleRate: Double + ) { + // Given + val rumContext = fakeSerializedRumContext.copy( + sessionStartReason = RumSessionScope.StartReason.INACTIVITY_TIMEOUT, + sessionSampleRate = fakeSampleRate.toFloat() + ) + + // When + val event = createEvent(rumContext = rumContext) + + // Then + assertThat(event.dd.session?.sessionPrecondition) + .isEqualTo(TimeseriesMemoryEvent.SessionPrecondition.INACTIVITY_TIMEOUT) + assertThat(event.dd.configuration?.sessionSampleRate?.toFloat()) + .isEqualTo(fakeSampleRate.toFloat()) + } + + @Test + fun `M fill dd configuration W create() { sample rates in features context }`( + @LongForgery(min = 0L, max = 100L) fakeSessionReplaySampleRate: Long, + @FloatForgery(min = 0f, max = 100f) fakeTraceSampleRate: Float + ) { + // Given + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to mapOf( + RumViewScope.SESSION_REPLAY_SAMPLE_RATE_KEY to fakeSessionReplaySampleRate + ), + Feature.TRACING_FEATURE_NAME to mapOf( + RumViewScope.TRACE_SAMPLE_RATE to fakeTraceSampleRate + ) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext) + + // Then + val configuration = checkNotNull(event.dd.configuration) + assertThat(configuration.sessionReplaySampleRate?.toLong()).isEqualTo(fakeSessionReplaySampleRate) + assertThat(configuration.traceSampleRate?.toFloat()).isEqualTo(fakeTraceSampleRate) + } + + @Test + fun `M fill dd configuration W create() { sample rates missing or of wrong type }`( + @StringForgery fakeNotASampleRate: String + ) { + // Given + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to emptyMap(), + Feature.TRACING_FEATURE_NAME to mapOf(RumViewScope.TRACE_SAMPLE_RATE to fakeNotASampleRate) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext) + + // Then + val configuration = checkNotNull(event.dd.configuration) + assertThat(configuration.sessionReplaySampleRate).isNull() + assertThat(configuration.traceSampleRate).isNull() + } + + @Test + fun `M fill session hasReplay W create() { view is recorded }`( + @StringForgery fakeViewId: String + ) { + // Given + val rumContext = fakeSerializedRumContext.copy(viewId = fakeViewId) + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to mapOf( + fakeViewId to mapOf(FeaturesContextResolver.HAS_REPLAY_KEY to true) + ) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext, rumContext = rumContext) + + // Then + assertThat(event.session.hasReplay).isTrue() + } + + @Test + fun `M fill session hasReplay W create() { view is not recorded }`( + @StringForgery fakeViewId: String + ) { + // Given + val rumContext = fakeSerializedRumContext.copy(viewId = fakeViewId) + val datadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext + mapOf( + Feature.SESSION_REPLAY_FEATURE_NAME to mapOf( + fakeViewId to mapOf(FeaturesContextResolver.HAS_REPLAY_KEY to false) + ) + ) + ) + + // When + val event = createEvent(datadogContext = datadogContext, rumContext = rumContext) + + // Then + assertThat(event.session.hasReplay).isFalse() + } + + @Test + fun `M fill synthetics W create() { synthetics ids are set }`( + @StringForgery fakeTestId: String, + @StringForgery fakeResultId: String + ) { + // Given + val rumContext = fakeSerializedRumContext.copy( + syntheticsTestId = fakeTestId, + syntheticsResultId = fakeResultId + ) + + // When + val event = createEvent(rumContext = rumContext) + + // Then + assertThat(event.synthetics?.testId).isEqualTo(fakeTestId) + assertThat(event.synthetics?.resultId).isEqualTo(fakeResultId) + } + + @ParameterizedTest + @MethodSource("incompleteSyntheticsIds") + fun `M not fill synthetics W create() { synthetics ids are incomplete }`( + syntheticsTestId: String?, + syntheticsResultId: String? + ) { + // Given + val rumContext = fakeSerializedRumContext.copy( + syntheticsTestId = syntheticsTestId, + syntheticsResultId = syntheticsResultId + ) + + // When + val event = createEvent(rumContext = rumContext) + + // Then + assertThat(event.synthetics).isNull() + } + + @Test + fun `M leave unsupported fields null W create()`() { + // When + val event = createEvent() + + // Then + assertThat(event.connectivity).isNull() + assertThat(event.usr).isNull() + assertThat(event.account).isNull() + assertThat(event.context).isNull() + assertThat(event.view).isNull() + assertThat(event.ciTest).isNull() + assertThat(event.display).isNull() + } + + private fun createSerializedEvent( + datadogContext: DatadogContext = fakeDatadogContext, + rumContext: RumContext = fakeSerializedRumContext, + sessionType: RumSessionType = RumSessionType.USER, + dataPoints: List> = oneSample + ): TimeseriesMemoryEvent = TimeseriesMemoryEvent.fromJson( + checkNotNull( + testedFactory(sessionType = sessionType) + .create(datadogContext, rumContext, dataPoints, emptyMap()) + ).toJson().toString() + ) + + private fun createEvent( + datadogContext: DatadogContext = fakeDatadogContext, + rumContext: RumContext = fakeSerializedRumContext, + sessionType: RumSessionType = RumSessionType.USER + ): TimeseriesMemoryEvent = checkNotNull( + testedFactory(sessionType = sessionType) + .create(datadogContext, rumContext, oneSample, emptyMap()) + ) + + companion object { + private const val PERCENT_FACTOR: Double = 100.0 + private const val BYTES_IN_KB: Double = 1000.0 + private const val MEMORY_OFFSET: Double = 0.0001 + + private const val VALUE_NAME_MEMORY: String = "memory" + private const val VALUE_SCHEMA_OBJECT: String = "object-v2" + + private const val FAKE_SYNTHETICS_ID: String = "synthetics-id" + + @JvmStatic + fun incompleteSyntheticsIds(): List = listOf( + Arguments.of(null, null), + Arguments.of("", " "), + Arguments.of(FAKE_SYNTHETICS_ID, null), + Arguments.of(null, FAKE_SYNTHETICS_ID), + Arguments.of(FAKE_SYNTHETICS_ID, " "), + Arguments.of("", FAKE_SYNTHETICS_ID) + ) + } +} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReaderTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReaderTest.kt index 00aed2e75f..ad7b954c7f 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReaderTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/CpuDatapointReaderTest.kt @@ -50,35 +50,35 @@ internal class CpuDatapointReaderTest { val mockCpuStatReader: CpuStatReader = mock() val mockTimeProvider: TimeProvider = mock { - on { getDeviceTimestampMillis() } doAnswer { fakeStartTimestampMs } + on { getServerTimestampMillis() } doAnswer { fakeStartTimestampMs } on { getDeviceElapsedTimeNanos() } doAnswer { fakeStartTimestampMs * NS_PER_MS } } private fun buildReader(availableProcessors: Int = 1) = CpuDatapointReader( cpuStatReader = mockCpuStatReader, - cpuTimeProvider = mockTimeProvider, + timeProvider = mockTimeProvider, intervalMs = fakeIntervalMs, availableProcessors = availableProcessors ) /** - * Primes the reader with [firstTicks] (returns null — no baseline yet), advances the clock - * by [elapsedMs], then returns the second sample built from [secondTicks] (or `null` to + * Primes the reader with [fakeBaselineTicks] (returns null — no baseline yet), advances the + * clock by [elapsedMs], then returns the second sample built from [secondTicks] (or `null` to * simulate the stat read failing between samples). Elapsed time is stubbed as a sequence so * the prime read sees the start instant and the second read sees start + [elapsedMs]. */ private fun readSecondSample( elapsedMs: Long, secondTicks: Double?, - availableProcessors: Int = 1, - firstTicks: Double = fakeBaselineTicks.toDouble() + availableProcessors: Int = 1 ): DataPoint? { whenever(mockTimeProvider.getDeviceElapsedTimeNanos()).doReturn( fakeStartTimestampMs * NS_PER_MS, (fakeStartTimestampMs + elapsedMs) * NS_PER_MS ) - whenever(mockTimeProvider.getDeviceTimestampMillis()) doReturn (fakeStartTimestampMs + elapsedMs) - whenever(mockCpuStatReader.readActiveTime()).doReturnConsecutively(listOf(firstTicks, secondTicks)) + whenever(mockTimeProvider.getServerTimestampMillis()) doReturn (fakeStartTimestampMs + elapsedMs) + whenever(mockCpuStatReader.readActiveTime()) + .doReturnConsecutively(listOf(fakeBaselineTicks.toDouble(), secondTicks)) return buildReader(availableProcessors).run { read() read() @@ -182,7 +182,7 @@ internal class CpuDatapointReaderTest { @Test fun `M normalise by core count W read() {multi-core usage}`( - @IntForgery(min = 1, max = 8) fakeCoreCount: Int, + @IntForgery(min = 2, max = 8) fakeCoreCount: Int, @LongForgery(min = 500L, max = 5000L) fakeElapsedMs: Long, @DoubleForgery(min = 1.0, max = 50.0) fakePerCorePct: Double ) { diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt index 61b45e83c3..d863626dfa 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt @@ -38,19 +38,19 @@ internal class VitalReaderWrapperTest { @LongForgery(min = 1L) var fakeTimestamp: Long = 0L + @LongForgery(min = 1L) + var fakeIntervalMs: Long = 0L + @Mock lateinit var mockTimeProvider: TimeProvider @BeforeEach fun `set up`() { - whenever(mockTimeProvider.getDeviceTimestampMillis()) doReturn fakeTimestamp + whenever(mockTimeProvider.getServerTimestampMillis()) doReturn fakeTimestamp } @Test - fun `M return sample W read() { reader has value }`( - @DoubleForgery(min = 0.001) fakeValue: Double, - @LongForgery(min = 1L) fakeIntervalMs: Long - ) { + fun `M return sample W read() { reader has value }`(@DoubleForgery fakeValue: Double) { // Given val mockVitalReader: VitalReader = mock { on { readVitalData() } doReturn fakeValue @@ -67,7 +67,7 @@ internal class VitalReaderWrapperTest { } @Test - fun `M return null W read() { reader has no value }`(@LongForgery(min = 1L) fakeIntervalMs: Long) { + fun `M return null W read() { reader has no value }`() { // Given val mockVitalReader: VitalReader = mock { on { readVitalData() } doReturn null @@ -80,14 +80,4 @@ internal class VitalReaderWrapperTest { // Then assertThat(result).isNull() } - - @Test - fun `M expose intervalMs W intervalMs { construction value }`(@LongForgery(min = 1L) fakeIntervalMs: Long) { - // Given - val mockVitalReader: VitalReader = mock() - val testedReader = VitalReaderWrapper(mockVitalReader, mockTimeProvider, fakeIntervalMs) - - // When / Then - assertThat(testedReader.intervalMs).isEqualTo(fakeIntervalMs) - } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializerTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializerTest.kt deleted file mode 100644 index 260998da04..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/CpuEventSerializerTest.kt +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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.rum.internal.timeseries.serializer - -import com.datadog.android.api.context.DatadogContext -import com.datadog.android.internal.time.TimeProvider -import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.assertj.TimeseriesCpuEventAssert.Companion.assertThat -import com.datadog.android.rum.internal.timeseries.DataPoint -import com.datadog.android.rum.model.TimeseriesCpuEvent -import com.datadog.android.rum.utils.forge.Configurator -import com.google.gson.JsonObject -import fr.xgouchet.elmyr.annotation.DoubleForgery -import fr.xgouchet.elmyr.annotation.Forgery -import fr.xgouchet.elmyr.annotation.LongForgery -import fr.xgouchet.elmyr.annotation.StringForgery -import fr.xgouchet.elmyr.junit5.ForgeConfiguration -import fr.xgouchet.elmyr.junit5.ForgeExtension -import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.data.Offset -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.junit.jupiter.api.extension.Extensions -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.junit.jupiter.MockitoSettings -import org.mockito.kotlin.doAnswer -import org.mockito.kotlin.mock -import org.mockito.quality.Strictness - -@Extensions( - ExtendWith(MockitoExtension::class), - ExtendWith(ForgeExtension::class) -) -@MockitoSettings(strictness = Strictness.LENIENT) -@ForgeConfiguration(Configurator::class) -internal class CpuEventSerializerTest { - - @LongForgery(min = 1L) - var fakeNowMs: Long = 0L - - @StringForgery - lateinit var fakeSessionId: String - - @StringForgery - lateinit var fakeApplicationId: String - - @Forgery - lateinit var fakeDatadogContext: DatadogContext - - val mockTimeProvider: TimeProvider = mock { - on { getDeviceTimestampMillis() } doAnswer { fakeNowMs } - } - - private fun testedSerializer( - sessionType: RumSessionType = RumSessionType.USER - ) = CpuEventSerializer( - sessionId = fakeSessionId, - applicationId = fakeApplicationId, - sessionType = sessionType, - timeProvider = mockTimeProvider - ) - - @Test - fun `M return null W serialize() { empty input }`() { - // When - val result = testedSerializer().serialize(fakeDatadogContext, emptyList()) - - // Then - assertThat(result).isNull() - } - - @Test - fun `M produce object schema W serialize() { compression off }`( - @DoubleForgery(min = 0.0, max = 100.0) fakeCpuValue: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // Given - val samples = listOf( - DataPoint(fakeTs, fakeCpuValue), - DataPoint(fakeTs + 1L, fakeCpuValue + 0.1) - ) - - // When - val json = testedSerializer().serialize(fakeDatadogContext, samples).failIfNull() - - // Then - assertThat(json) - .hasDate(fakeNowMs) - .hasValidTimeseriesId() - .hasTimeseriesDataCount(2) - .hasTimeseriesStart(fakeTs) - .hasTimeseriesEnd(fakeTs + 1L) - .hasApplicationId(fakeApplicationId) - .hasSessionType(TimeseriesCpuEvent.Type.USER) - .hasTimeseriesSchema("object-v2") - .hasService(fakeDatadogContext.service) - .hasVersion(fakeDatadogContext.version) - } - - @Test - fun `M map session type W serialize() { synthetics }`( - @DoubleForgery(min = 0.0, max = 100.0) fakeCpuValue: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // Given - val samples = listOf(DataPoint(fakeTs, fakeCpuValue)) - - // When - val json = testedSerializer(sessionType = RumSessionType.SYNTHETICS) - .serialize(fakeDatadogContext, samples) - .failIfNull() - - // Then - assertThat(json).hasSessionType(TimeseriesCpuEvent.Type.SYNTHETICS) - } - - @Test - fun `M preserve cpu_usage W serialize() { object schema }`( - @DoubleForgery(min = 1.0, max = 100.0) fakeCpu: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // Given - val samples = listOf( - DataPoint(fakeTs, fakeCpu), - DataPoint(fakeTs + 1L, fakeCpu) - ) - - // When - val json = testedSerializer().serialize(fakeDatadogContext, samples).failIfNull() - - // Then - assertThat(json) - .hasCpuUsage(fakeCpu, Offset.offset(CPU_OFFSET), position = 0) - } - - private companion object { - private const val CPU_OFFSET: Double = 0.0001 - private const val NON_NULL_JSON_ERROR: String = "expected non-null json" - private fun JsonObject?.failIfNull(): JsonObject { - if (this == null) error(NON_NULL_JSON_ERROR) else return this - } - } -} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializerTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializerTest.kt deleted file mode 100644 index a24132ac68..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/serializer/MemoryEventSerializerTest.kt +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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.rum.internal.timeseries.serializer - -import com.datadog.android.api.context.DatadogContext -import com.datadog.android.internal.time.TimeProvider -import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.internal.timeseries.DataPoint -import com.datadog.android.rum.model.TimeseriesMemoryEvent -import com.datadog.android.rum.utils.forge.Configurator -import fr.xgouchet.elmyr.annotation.DoubleForgery -import fr.xgouchet.elmyr.annotation.Forgery -import fr.xgouchet.elmyr.annotation.LongForgery -import fr.xgouchet.elmyr.annotation.StringForgery -import fr.xgouchet.elmyr.junit5.ForgeConfiguration -import fr.xgouchet.elmyr.junit5.ForgeExtension -import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.data.Offset -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow -import org.junit.jupiter.api.extension.ExtendWith -import org.junit.jupiter.api.extension.Extensions -import org.mockito.Mock -import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.junit.jupiter.MockitoSettings -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.whenever -import org.mockito.quality.Strictness -import java.util.UUID - -@Extensions( - ExtendWith(MockitoExtension::class), - ExtendWith(ForgeExtension::class) -) -@MockitoSettings(strictness = Strictness.LENIENT) -@ForgeConfiguration(Configurator::class) -internal class MemoryEventSerializerTest { - - @Mock - lateinit var mockTimeProvider: TimeProvider - - @StringForgery - lateinit var fakeSessionId: String - - @StringForgery - lateinit var fakeApplicationId: String - - @LongForgery(min = 1_000_000_000L, max = 16_000_000_000L) - var fakeTotalRamBytes: Long = 0L - - @LongForgery(min = 1L) - var fakeNowMs: Long = 0L - - @Forgery - lateinit var fakeDatadogContext: DatadogContext - - @BeforeEach - fun `set up`() { - whenever(mockTimeProvider.getDeviceTimestampMillis()) doReturn fakeNowMs - } - - private fun testedSerializer( - sessionType: RumSessionType = RumSessionType.USER, - totalRamBytes: Long = fakeTotalRamBytes - ) = MemoryEventSerializer( - sessionId = fakeSessionId, - applicationId = fakeApplicationId, - sessionType = sessionType, - totalRamBytes = totalRamBytes, - timeProvider = mockTimeProvider - ) - - @Test - fun `M return null W serialize() { empty input }`() { - // When - val result = testedSerializer().serialize(fakeDatadogContext, emptyList()) - - // Then - assertThat(result).isNull() - } - - @Test - fun `M return null W serialize() { totalRamBytes is zero }`( - @DoubleForgery(min = 1.0) fakeMemory: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // When - val result = testedSerializer(totalRamBytes = 0L) - .serialize(fakeDatadogContext, listOf(DataPoint(fakeTs, fakeMemory))) - - // Then - assertThat(result).isNull() - } - - @Test - fun `M return null W serialize() { totalRamBytes is negative }`( - @LongForgery(max = -1L) fakeNegativeRam: Long, - @DoubleForgery(min = 1.0) fakeMemory: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // When - val result = testedSerializer(totalRamBytes = fakeNegativeRam) - .serialize(fakeDatadogContext, listOf(DataPoint(fakeTs, fakeMemory))) - - // Then - assertThat(result).isNull() - } - - @Test - fun `M produce object schema W serialize() { compression off }`( - @DoubleForgery(min = 1.0) fakeMemory: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // Given - val samples = listOf( - DataPoint(fakeTs, fakeMemory), - DataPoint(fakeTs + 1L, fakeMemory + 1.0) - ) - - // When - val result = testedSerializer().serialize(fakeDatadogContext, samples) - - // Then - val json = checkNotNull(result) - val timeseries = json.getAsJsonObject(TimeseriesAttributes.KEY_TIMESERIES) - assertThat(timeseries.get(TimeseriesAttributes.KEY_SCHEMA).asString).isEqualTo(VALUE_SCHEMA_OBJECT) - assertThat(timeseries.get(KEY_START).asLong).isEqualTo(fakeTs) - assertThat(timeseries.get(KEY_END).asLong).isEqualTo(fakeTs + 1L) - assertDoesNotThrow { UUID.fromString(timeseries.get(KEY_ID).asString) } - assertThat(json.get(KEY_SERVICE).asString).isEqualTo(fakeDatadogContext.service) - assertThat(json.get(KEY_VERSION).asString).isEqualTo(fakeDatadogContext.version) - - val parsed = TimeseriesMemoryEvent.fromJsonObject(json) - assertThat(parsed.timeseries.data.timestamps).hasSize(2) - assertThat(parsed.timeseries.data.values.memoryFootprint.first().toDouble()) - .isCloseTo(fakeMemory / 1000.0, Offset.offset(MEMORY_OFFSET)) - assertThat(parsed.timeseries.data.values.memoryPercent.first().toDouble()) - .isCloseTo(fakeMemory / fakeTotalRamBytes * PERCENT_FACTOR, Offset.offset(MEMORY_OFFSET)) - } - - @Test - fun `M map session type W serialize() { synthetics }`( - @DoubleForgery(min = 1.0) fakeMemory: Double, - @LongForgery(min = 1L) fakeTs: Long - ) { - // When - val result = testedSerializer(sessionType = RumSessionType.SYNTHETICS) - .serialize(fakeDatadogContext, listOf(DataPoint(fakeTs, fakeMemory), DataPoint(fakeTs + 1L, fakeMemory))) - - // Then - val json = checkNotNull(result) - assertThat(json.getAsJsonObject(KEY_SESSION).get(KEY_TYPE).asString).isEqualTo(VALUE_TYPE_SYNTHETICS) - } - - private companion object { - private const val PERCENT_FACTOR: Double = 100.0 - private const val MEMORY_OFFSET: Double = 0.0001 - - // JSON keys - private const val KEY_SESSION: String = "session" - private const val KEY_TYPE: String = "type" - private const val KEY_ID: String = "id" - private const val KEY_START: String = "start" - private const val KEY_END: String = "end" - private const val KEY_SERVICE: String = "service" - private const val KEY_VERSION: String = "version" - - // JSON values - private const val VALUE_SCHEMA_OBJECT: String = "object-v2" - private const val VALUE_TYPE_SYNTHETICS: String = "synthetics" - } -} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/CpuStatReaderTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/CpuStatReaderTest.kt index 4dd0917e25..edab0078be 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/CpuStatReaderTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/vitals/CpuStatReaderTest.kt @@ -92,7 +92,7 @@ internal class CpuStatReaderTest { } @Test - fun `M use default stat file W init()`() { + fun `M use default stat file W init() {no file provided}`() { // When val reader = CpuStatReader(internalLogger = mock()) @@ -113,18 +113,18 @@ internal class CpuStatReaderTest { } @Test - fun `M read utime W readUserTime() {multiple times}`(@IntForgery(1) utimes: List) { + fun `M read utime W readUserTime() {multiple times}`(@IntForgery(1) fakeUtimes: List) { // Given val results = mutableListOf() // When - utimes.forEach { utime -> + fakeUtimes.forEach { utime -> fakeFile.writeText(generateStatContent(utime)) results.add(testedReader.readUserTime()) } // Then - assertThat(results).isEqualTo(utimes.map { it.toDouble() }) + assertThat(results).isEqualTo(fakeUtimes.map { it.toDouble() }) } @Test diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt deleted file mode 100644 index 44c041ba85..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.rum.timeseries - -import com.datadog.android.rum.ExperimentalRumApi -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -@OptIn(ExperimentalRumApi::class) -internal class TimeseriesConfigurationTest { - - @Test - fun `M use defaults W built with no args`() { - // When - val config = TimeseriesConfiguration.Builder().build() - - // Then - assertThat(config.bufferSize).isEqualTo(TimeseriesConfiguration.DEFAULT_BUFFER_SIZE) - assertThat(config.intervalMs).isEqualTo(TimeseriesConfiguration.DEFAULT_INTERVAL_MS) - } - - @Test - fun `M use default bufferSize W setBufferSize with non-positive value`() { - // When - val configZero = TimeseriesConfiguration.Builder().setBufferSize(0).build() - val configNegative = TimeseriesConfiguration.Builder().setBufferSize(-1).build() - - // Then - assertThat(configZero.bufferSize).isEqualTo(TimeseriesConfiguration.DEFAULT_BUFFER_SIZE) - assertThat(configNegative.bufferSize).isEqualTo(TimeseriesConfiguration.DEFAULT_BUFFER_SIZE) - } - - @Test - fun `M use default intervalMs W setIntervalMs below minimum`() { - // When - val configBelowMin = TimeseriesConfiguration.Builder() - .setIntervalMs(TimeseriesConfiguration.MIN_INTERVAL_MS - 1) - .build() - val configZero = TimeseriesConfiguration.Builder().setIntervalMs(0L).build() - - // Then - assertThat(configBelowMin.intervalMs).isEqualTo(TimeseriesConfiguration.DEFAULT_INTERVAL_MS) - assertThat(configZero.intervalMs).isEqualTo(TimeseriesConfiguration.DEFAULT_INTERVAL_MS) - } - - @Test - fun `M store provided values W built with valid args`() { - // Given - val fakeBufferSize = 10 - val fakeIntervalMs = 500L - - // When - val config = TimeseriesConfiguration.Builder() - .setBufferSize(fakeBufferSize) - .setIntervalMs(fakeIntervalMs) - .build() - - // Then - assertThat(config.bufferSize).isEqualTo(fakeBufferSize) - assertThat(config.intervalMs).isEqualTo(fakeIntervalMs) - } -} diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTests.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTests.kt new file mode 100644 index 0000000000..1c3575ae9d --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTests.kt @@ -0,0 +1,49 @@ +/* + * 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.rum.timeseries + +import com.datadog.android.rum.ExperimentalRumApi +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +@OptIn(ExperimentalRumApi::class) +internal class TimeseriesConfigurationTests { + + @Test + fun `M collect all types W build() { collectOnly not called }`() { + // When + val config = TimeseriesConfiguration.Builder().build() + + // Then + assertThat(config.enabledTypes).containsExactlyInAnyOrderElementsOf(TimeseriesType.values().toList()) + } + + @ParameterizedTest + @EnumSource(TimeseriesType::class) + fun `M collect selected type W collectOnly()`(fakeType: TimeseriesType) { + // When + val config = TimeseriesConfiguration.Builder() + .collectOnly(fakeType) + .build() + + // Then + assertThat(config.enabledTypes).containsExactly(fakeType) + } + + @Test + fun `M collect no types W collectOnly() { empty array }`() { + // When + val config = TimeseriesConfiguration.Builder() + .collectOnly(*emptyArray()) + .build() + + // Then + assertThat(config.enabledTypes).isEmpty() + } +} diff --git a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch1.json b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch1.json index 1d5b4ecc97..9808a056a7 100644 --- a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch1.json +++ b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch1.json @@ -1,10 +1,55 @@ { - "type": "timeseries", - "_dd": {"format_version": 2}, - "application": {"id": "fake-app-id"}, - "session": {"id": "fake-session-id", "type": "user"}, - "source": "android", "date": 1700000001000, + "application": { + "id": "fake-app-id", + "current_locale": "en-US" + }, + "service": "fake-service", + "version": "1.2.3", + "build_version": "42", + "build_id": "fake-app-build-id", + "ddtags": "service:fake-service,version:1.2.3,sdk_version:2.0.0,env:fake-env,variant:fake-variant", + "session": { + "id": "fake-session-id", + "type": "user", + "has_replay": true + }, + "source": "android", + "os": { + "name": "Android", + "version": "13.0.1", + "version_major": "13" + }, + "device": { + "type": "mobile", + "name": "fake-device-name", + "model": "fake-device-model", + "brand": "fake-device-brand", + "architecture": "arm64-v8a", + "locales": [ + "en-US", + "fr-FR" + ], + "time_zone": "America/New_York", + "battery_level": 0.42, + "power_saving_mode": true, + "brightness_level": 128, + "logical_cpu_count": 8, + "total_ram": 4096, + "is_low_ram": false + }, + "_dd": { + "format_version": 2, + "session": { + "session_precondition": "user_app_launch" + }, + "configuration": { + "session_sample_rate": 42.0, + "session_replay_sample_rate": 75, + "trace_sample_rate": 20.0 + } + }, + "type": "timeseries", "timeseries": { "id": "00000000-0000-0000-0000-000000000000", "name": "cpu", @@ -12,9 +57,21 @@ "start": 1700000001000000000, "end": 1700000005000000000, "data": { - "timestamps": [1700000001000000000, 1700000002000000000, 1700000003000000000, 1700000004000000000, 1700000005000000000], + "timestamps": [ + 1700000001000000000, + 1700000002000000000, + 1700000003000000000, + 1700000004000000000, + 1700000005000000000 + ], "values": { - "cpu_usage": [12.5, 14.2, 11.8, 16.3, 13.7] + "cpu_usage": [ + 12.5, + 14.2, + 11.8, + 16.3, + 13.7 + ] } } } diff --git a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch2.json b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch2.json index 6415084548..80fce478c4 100644 --- a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch2.json +++ b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_cpu_batch2.json @@ -1,10 +1,55 @@ { - "type": "timeseries", - "_dd": {"format_version": 2}, - "application": {"id": "fake-app-id"}, - "session": {"id": "fake-session-id", "type": "user"}, - "source": "android", "date": 1700000001000, + "application": { + "id": "fake-app-id", + "current_locale": "en-US" + }, + "service": "fake-service", + "version": "1.2.3", + "build_version": "42", + "build_id": "fake-app-build-id", + "ddtags": "service:fake-service,version:1.2.3,sdk_version:2.0.0,env:fake-env,variant:fake-variant", + "session": { + "id": "fake-session-id", + "type": "user", + "has_replay": true + }, + "source": "android", + "os": { + "name": "Android", + "version": "13.0.1", + "version_major": "13" + }, + "device": { + "type": "mobile", + "name": "fake-device-name", + "model": "fake-device-model", + "brand": "fake-device-brand", + "architecture": "arm64-v8a", + "locales": [ + "en-US", + "fr-FR" + ], + "time_zone": "America/New_York", + "battery_level": 0.42, + "power_saving_mode": true, + "brightness_level": 128, + "logical_cpu_count": 8, + "total_ram": 4096, + "is_low_ram": false + }, + "_dd": { + "format_version": 2, + "session": { + "session_precondition": "user_app_launch" + }, + "configuration": { + "session_sample_rate": 42.0, + "session_replay_sample_rate": 75, + "trace_sample_rate": 20.0 + } + }, + "type": "timeseries", "timeseries": { "id": "00000000-0000-0000-0000-000000000000", "name": "cpu", @@ -12,9 +57,21 @@ "start": 1700000006000000000, "end": 1700000010000000000, "data": { - "timestamps": [1700000006000000000, 1700000007000000000, 1700000008000000000, 1700000009000000000, 1700000010000000000], + "timestamps": [ + 1700000006000000000, + 1700000007000000000, + 1700000008000000000, + 1700000009000000000, + 1700000010000000000 + ], "values": { - "cpu_usage": [18.1, 22.4, 19.6, 15.9, 13.2] + "cpu_usage": [ + 18.1, + 22.4, + 19.6, + 15.9, + 13.2 + ] } } } diff --git a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch1.json b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch1.json index 4723b0d1cb..c3eb2f54c2 100644 --- a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch1.json +++ b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch1.json @@ -1,10 +1,55 @@ { - "type": "timeseries", - "_dd": {"format_version": 2}, - "application": {"id": "fake-app-id"}, - "session": {"id": "fake-session-id", "type": "user"}, - "source": "android", "date": 1700000001000, + "application": { + "id": "fake-app-id", + "current_locale": "en-US" + }, + "service": "fake-service", + "version": "1.2.3", + "build_version": "42", + "build_id": "fake-app-build-id", + "ddtags": "service:fake-service,version:1.2.3,sdk_version:2.0.0,env:fake-env,variant:fake-variant", + "session": { + "id": "fake-session-id", + "type": "user", + "has_replay": true + }, + "source": "android", + "os": { + "name": "Android", + "version": "13.0.1", + "version_major": "13" + }, + "device": { + "type": "mobile", + "name": "fake-device-name", + "model": "fake-device-model", + "brand": "fake-device-brand", + "architecture": "arm64-v8a", + "locales": [ + "en-US", + "fr-FR" + ], + "time_zone": "America/New_York", + "battery_level": 0.42, + "power_saving_mode": true, + "brightness_level": 128, + "logical_cpu_count": 8, + "total_ram": 4096, + "is_low_ram": false + }, + "_dd": { + "format_version": 2, + "session": { + "session_precondition": "user_app_launch" + }, + "configuration": { + "session_sample_rate": 42.0, + "session_replay_sample_rate": 75, + "trace_sample_rate": 20.0 + } + }, + "type": "timeseries", "timeseries": { "id": "00000000-0000-0000-0000-000000000000", "name": "memory", @@ -12,10 +57,28 @@ "start": 1700000001000000000, "end": 1700000005000000000, "data": { - "timestamps": [1700000001000000000, 1700000002000000000, 1700000003000000000, 1700000004000000000, 1700000005000000000], + "timestamps": [ + 1700000001000000000, + 1700000002000000000, + 1700000003000000000, + 1700000004000000000, + 1700000005000000000 + ], "values": { - "memory_footprint": [31233.3, 31245.5, 31300.8, 31289.1, 31350.0], - "memory_percent": [3.12333, 3.12455, 3.13008, 3.12891, 3.135] + "memory_footprint": [ + 31233.3, + 31245.5, + 31300.8, + 31289.1, + 31350.0 + ], + "memory_percent": [ + 3.12333, + 3.12455, + 3.13008, + 3.12891, + 3.135 + ] } } } diff --git a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch2.json b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch2.json index ab5b91113d..ed1a216f6c 100644 --- a/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch2.json +++ b/features/dd-sdk-android-rum/src/test/resources/fixtures/timeseries/expected_memory_batch2.json @@ -1,10 +1,55 @@ { - "type": "timeseries", - "_dd": {"format_version": 2}, - "application": {"id": "fake-app-id"}, - "session": {"id": "fake-session-id", "type": "user"}, - "source": "android", "date": 1700000001000, + "application": { + "id": "fake-app-id", + "current_locale": "en-US" + }, + "service": "fake-service", + "version": "1.2.3", + "build_version": "42", + "build_id": "fake-app-build-id", + "ddtags": "service:fake-service,version:1.2.3,sdk_version:2.0.0,env:fake-env,variant:fake-variant", + "session": { + "id": "fake-session-id", + "type": "user", + "has_replay": true + }, + "source": "android", + "os": { + "name": "Android", + "version": "13.0.1", + "version_major": "13" + }, + "device": { + "type": "mobile", + "name": "fake-device-name", + "model": "fake-device-model", + "brand": "fake-device-brand", + "architecture": "arm64-v8a", + "locales": [ + "en-US", + "fr-FR" + ], + "time_zone": "America/New_York", + "battery_level": 0.42, + "power_saving_mode": true, + "brightness_level": 128, + "logical_cpu_count": 8, + "total_ram": 4096, + "is_low_ram": false + }, + "_dd": { + "format_version": 2, + "session": { + "session_precondition": "user_app_launch" + }, + "configuration": { + "session_sample_rate": 42.0, + "session_replay_sample_rate": 75, + "trace_sample_rate": 20.0 + } + }, + "type": "timeseries", "timeseries": { "id": "00000000-0000-0000-0000-000000000000", "name": "memory", @@ -12,10 +57,28 @@ "start": 1700000006000000000, "end": 1700000010000000000, "data": { - "timestamps": [1700000006000000000, 1700000007000000000, 1700000008000000000, 1700000009000000000, 1700000010000000000], + "timestamps": [ + 1700000006000000000, + 1700000007000000000, + 1700000008000000000, + 1700000009000000000, + 1700000010000000000 + ], "values": { - "memory_footprint": [31420.2, 31510.4, 31498.7, 31550.3, 31600.1], - "memory_percent": [3.14202, 3.15104, 3.14987, 3.15503, 3.16001] + "memory_footprint": [ + 31420.2, + 31510.4, + 31498.7, + 31550.3, + 31600.1 + ], + "memory_percent": [ + 3.14202, + 3.15104, + 3.14987, + 3.15503, + 3.16001 + ] } } } diff --git a/features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt b/features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt new file mode 100644 index 0000000000..c93475340d --- /dev/null +++ b/features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesCpuEventAssert.kt @@ -0,0 +1,169 @@ +/* + * 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.rum.assertj + +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesCpuEvent.TimeseriesCpuEventSessionType +import org.assertj.core.api.Assertions +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.data.Offset +import java.util.UUID + +class TimeseriesCpuEventAssert private constructor( + private val actual: TimeseriesCpuEvent +) { + + fun hasApplicationId(expected: String) = apply { + assertThat(actual.application.id) + .overridingErrorMessage { + "Expected event to have application.id $expected " + + "but was ${actual.application.id}" + } + .isEqualTo(expected) + } + + fun hasSessionId(expected: String) = apply { + assertThat(actual.session.id) + .overridingErrorMessage { + "Expected event to have session.id $expected but was ${actual.session.id}" + } + .isEqualTo(expected) + } + + fun hasSessionType(expected: TimeseriesCpuEventSessionType) = apply { + assertThat(actual.session.type) + .overridingErrorMessage { + "Expected event to have session.type $expected but was ${actual.session.type}" + } + .isEqualTo(expected) + } + + fun hasService(expected: String) = apply { + assertThat(actual.service) + .overridingErrorMessage { "Expected event to have service $expected but was ${actual.service}" } + .isEqualTo(expected) + } + + fun hasVersion(expected: String) = apply { + assertThat(actual.version) + .overridingErrorMessage { "Expected event to have version $expected but was ${actual.version}" } + .isEqualTo(expected) + } + + fun hasDate(expected: Long) = apply { + assertThat(actual.date) + .overridingErrorMessage { "Expected event to have date $expected but was ${actual.date}" } + .isEqualTo(expected) + } + + fun hasTimeseriesName(expected: String) = apply { + assertThat(actual.timeseries.name) + .overridingErrorMessage { + "Expected event to have timeseries.name $expected but was ${actual.timeseries.name}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesSchema(expected: String) = apply { + assertThat(actual.timeseries.schema) + .overridingErrorMessage { + "Expected event to have timeseries.schema $expected but was ${actual.timeseries.schema}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesStart(expected: Long) = apply { + assertThat(actual.timeseries.start) + .overridingErrorMessage { + "Expected event to have timeseries.start $expected but was ${actual.timeseries.start}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesEnd(expected: Long) = apply { + assertThat(actual.timeseries.end) + .overridingErrorMessage { + "Expected event to have timeseries.end $expected but was ${actual.timeseries.end}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesStartNotAfterEnd() = apply { + assertThat(actual.timeseries.start) + .overridingErrorMessage { + "Expected timeseries.start ${actual.timeseries.start} to be less than or equal to " + + "timeseries.end ${actual.timeseries.end}" + } + .isLessThanOrEqualTo(actual.timeseries.end) + } + + fun hasValidTimeseriesId() = apply { + val parsedTimeseriesId = runCatching { UUID.fromString(actual.timeseries.id) }.getOrNull() + + assertThat(parsedTimeseriesId) + .overridingErrorMessage { "Expected timeseries.id to be a valid UUID but was ${actual.timeseries.id}" } + .isNotNull() + } + + fun hasSameTimeseriesAs(expected: TimeseriesCpuEvent) = apply { + val expectedCpuUsage = expected.timeseries.data.values.cpuUsage + val actualCpuUsage = actual.timeseries.data.values.cpuUsage + + hasTimeseriesName(expected.timeseries.name) + .hasTimeseriesSchema(expected.timeseries.schema) + .hasTimeseriesStart(expected.timeseries.start) + .hasTimeseriesEnd(expected.timeseries.end) + .hasTimestamps(*expected.timeseries.data.timestamps.toLongArray()) + + assertThat(actualCpuUsage) + .overridingErrorMessage { + "Expected CPU values count ${expectedCpuUsage.size} but was ${actualCpuUsage.size}" + } + .hasSameSizeAs(expectedCpuUsage) + + expectedCpuUsage.forEachIndexed { position, expectedValue -> + hasCpuUsage(expectedValue.toDouble(), position) + } + } + + fun hasDataPointsCount(expected: Int) = apply { + val timestampsCount = actual.timeseries.data.timestamps.size + + assertThat(timestampsCount) + .overridingErrorMessage { + "Expected timeseries data to contain $expected datapoints but contained $timestampsCount" + } + .isEqualTo(expected) + } + + fun hasTimestamps(vararg expected: Long) = apply { + assertThat(actual.timeseries.data.timestamps) + .overridingErrorMessage { + "Expected timeseries timestamps ${expected.toList()} but was ${actual.timeseries.data.timestamps}" + } + .containsExactlyElementsOf(expected.toList()) + } + + fun hasCpuUsage(expected: Double, position: Int = 0) = apply { + val cpuUsage = actual.timeseries.data.values.cpuUsage.getOrNull(position)?.toDouble() + + assertThat(checkNotNull(cpuUsage)) + .overridingErrorMessage { "Expected first data point cpu_usage to be close to $expected but was $cpuUsage" } + .isCloseTo(expected, Offset.offset(NUMBER_COMPARISON_TOLERANCE)) + } + + companion object { + private const val NUMBER_COMPARISON_TOLERANCE = 1e-9 + + fun assertThat(actual: TimeseriesCpuEvent?): TimeseriesCpuEventAssert { + Assertions.assertThat(actual) + .overridingErrorMessage { "Expected timeseries event to be present" } + .isNotNull() + return TimeseriesCpuEventAssert(checkNotNull(actual)) + } + } +} diff --git a/features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesMemoryEventAssert.kt b/features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesMemoryEventAssert.kt new file mode 100644 index 0000000000..33837b7b57 --- /dev/null +++ b/features/dd-sdk-android-rum/src/testFixtures/kotlin/com/datadog/android/rum/assertj/TimeseriesMemoryEventAssert.kt @@ -0,0 +1,203 @@ +/* + * 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.rum.assertj + +import com.datadog.android.rum.model.TimeseriesMemoryEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent.TimeseriesMemoryEventSessionType +import org.assertj.core.api.Assertions +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.data.Offset +import java.util.UUID + +class TimeseriesMemoryEventAssert private constructor( + private val actual: TimeseriesMemoryEvent +) { + + fun hasApplicationId(expected: String) = apply { + assertThat(actual.application.id) + .overridingErrorMessage { + "Expected event to have application.id $expected " + + "but was ${actual.application.id}" + } + .isEqualTo(expected) + } + + fun hasSessionId(expected: String) = apply { + assertThat(actual.session.id) + .overridingErrorMessage { + "Expected event to have session.id $expected but was ${actual.session.id}" + } + .isEqualTo(expected) + } + + fun hasSessionType(expected: TimeseriesMemoryEventSessionType) = apply { + assertThat(actual.session.type) + .overridingErrorMessage { + "Expected event to have session.type $expected but was ${actual.session.type}" + } + .isEqualTo(expected) + } + + fun hasService(expected: String) = apply { + assertThat(actual.service) + .overridingErrorMessage { "Expected event to have service $expected but was ${actual.service}" } + .isEqualTo(expected) + } + + fun hasVersion(expected: String) = apply { + assertThat(actual.version) + .overridingErrorMessage { "Expected event to have version $expected but was ${actual.version}" } + .isEqualTo(expected) + } + + fun hasDate(expected: Long) = apply { + assertThat(actual.date) + .overridingErrorMessage { "Expected event to have date $expected but was ${actual.date}" } + .isEqualTo(expected) + } + + fun hasTimeseriesName(expected: String) = apply { + assertThat(actual.timeseries.name) + .overridingErrorMessage { + "Expected event to have timeseries.name $expected but was ${actual.timeseries.name}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesSchema(expected: String) = apply { + assertThat(actual.timeseries.schema) + .overridingErrorMessage { + "Expected event to have timeseries.schema $expected but was ${actual.timeseries.schema}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesStart(expected: Long) = apply { + assertThat(actual.timeseries.start) + .overridingErrorMessage { + "Expected event to have timeseries.start $expected but was ${actual.timeseries.start}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesEnd(expected: Long) = apply { + assertThat(actual.timeseries.end) + .overridingErrorMessage { + "Expected event to have timeseries.end $expected but was ${actual.timeseries.end}" + } + .isEqualTo(expected) + } + + fun hasTimeseriesStartNotAfterEnd() = apply { + assertThat(actual.timeseries.start) + .overridingErrorMessage { + "Expected timeseries.start ${actual.timeseries.start} to be less than or equal to " + + "timeseries.end ${actual.timeseries.end}" + } + .isLessThanOrEqualTo(actual.timeseries.end) + } + + fun hasValidTimeseriesId() = apply { + val parsedTimeseriesId = runCatching { UUID.fromString(actual.timeseries.id) }.getOrNull() + + assertThat(parsedTimeseriesId) + .overridingErrorMessage { "Expected timeseries.id to be a valid UUID but was ${actual.timeseries.id}" } + .isNotNull() + } + + fun hasSameTimeseriesAs(expected: TimeseriesMemoryEvent) = apply { + val expectedTimeseries = expected.timeseries + val expectedMemoryFootprint = expectedTimeseries.data.values.memoryFootprint + val actualMemoryFootprint = actual.timeseries.data.values.memoryFootprint + val expectedMemoryPercent = expectedTimeseries.data.values.memoryPercent + val actualMemoryPercent = actual.timeseries.data.values.memoryPercent + + hasTimeseriesName(expectedTimeseries.name) + .hasTimeseriesSchema(expectedTimeseries.schema) + .hasTimeseriesStart(expectedTimeseries.start) + .hasTimeseriesEnd(expectedTimeseries.end) + .hasTimestamps(*expectedTimeseries.data.timestamps.toLongArray()) + + assertThat(actualMemoryFootprint) + .overridingErrorMessage { + "Expected memory footprint values count ${expectedMemoryFootprint.size} " + + "but was ${actualMemoryFootprint.size}" + } + .hasSameSizeAs(expectedMemoryFootprint) + assertThat(actualMemoryPercent) + .overridingErrorMessage { + "Expected memory percent values count ${expectedMemoryPercent.size} " + + "but was ${actualMemoryPercent.size}" + } + .hasSameSizeAs(expectedMemoryPercent) + expectedMemoryFootprint.forEachIndexed { position, expectedValue -> + hasMemoryFootprint(expectedValue.toDouble(), NUMBER_COMPARISON_TOLERANCE, position) + } + expectedMemoryPercent.forEachIndexed { position, expectedValue -> + hasMemoryPercent(expectedValue.toDouble(), NUMBER_COMPARISON_TOLERANCE, position) + } + } + + fun hasDataPointsCount(expected: Int) = apply { + val timestampsCount = actual.timeseries.data.timestamps.size + + assertThat(timestampsCount) + .overridingErrorMessage { + "Expected timeseries data to contain $expected datapoints but contained $timestampsCount" + } + .isEqualTo(expected) + } + + fun hasTimestamps(vararg expected: Long) = apply { + assertThat(actual.timeseries.data.timestamps) + .overridingErrorMessage { + "Expected timeseries timestamps ${expected.toList()} but was ${actual.timeseries.data.timestamps}" + } + .containsExactlyElementsOf(expected.toList()) + } + + fun hasMemoryFootprint(expected: Double, offset: Double, position: Int = 0) = apply { + val memoryFootprint = actual.timeseries.data.values.memoryFootprint.getOrNull(position)?.toDouble() + + assertThat(memoryFootprint) + .overridingErrorMessage { + "Expected memory footprint data point at position $position to be present" + } + .isNotNull() + assertThat(checkNotNull(memoryFootprint)) + .overridingErrorMessage { + "Expected memory footprint at position $position to be close to $expected but was $memoryFootprint" + } + .isCloseTo(expected, Offset.offset(offset)) + } + + fun hasMemoryPercent(expected: Double, offset: Double, position: Int = 0) = apply { + val memoryPercent = actual.timeseries.data.values.memoryPercent.getOrNull(position)?.toDouble() + + assertThat(memoryPercent) + .overridingErrorMessage { + "Expected memory percent data point at position $position to be present" + } + .isNotNull() + assertThat(checkNotNull(memoryPercent)) + .overridingErrorMessage { + "Expected memory percent at position $position to be close to $expected but was $memoryPercent" + } + .isCloseTo(expected, Offset.offset(offset)) + } + + companion object { + private const val NUMBER_COMPARISON_TOLERANCE = 1e-9 + + fun assertThat(actual: TimeseriesMemoryEvent?): TimeseriesMemoryEventAssert { + Assertions.assertThat(actual) + .overridingErrorMessage { "Expected timeseries event to be present" } + .isNotNull() + return TimeseriesMemoryEventAssert(checkNotNull(actual)) + } + } +} From 43297b993d3941adbcf0a7b733d971267895d5ac Mon Sep 17 00:00:00 2001 From: Timur Valeev Date: Fri, 14 Aug 2026 14:40:44 +0100 Subject: [PATCH 4/4] RUM-17613 Add integration tests for timeseries collection Add a playground activity and an instrumented test that assert CPU and memory timeseries are collected, flushed on backgrounding and resumed on return to foreground. Ref: RUM-17613 --- features/dd-sdk-android-rum/build.gradle.kts | 2 + instrumented/integration/build.gradle.kts | 6 + .../rum/TimeseriesCollectionTest.kt | 162 ++++++++++++++++++ .../integration/src/main/AndroidManifest.xml | 3 + .../TimeseriesTrackingPlaygroundActivity.kt | 52 ++++++ 5 files changed, 225 insertions(+) create mode 100644 instrumented/integration/src/androidTest/kotlin/com/datadog/android/sdk/integration/rum/TimeseriesCollectionTest.kt create mode 100644 instrumented/integration/src/main/kotlin/com/datadog/android/sdk/integration/rum/TimeseriesTrackingPlaygroundActivity.kt diff --git a/features/dd-sdk-android-rum/build.gradle.kts b/features/dd-sdk-android-rum/build.gradle.kts index e96e393251..4a3267844a 100644 --- a/features/dd-sdk-android-rum/build.gradle.kts +++ b/features/dd-sdk-android-rum/build.gradle.kts @@ -105,7 +105,9 @@ dependencies { ) } } + testFixturesImplementation(libs.gson) testFixturesImplementation(libs.kotlin) + testFixturesImplementation(libs.jUnit4) testFixturesImplementation(libs.bundles.jUnit5) testFixturesImplementation(libs.okHttp) testFixturesImplementation(libs.bundles.testTools) diff --git a/instrumented/integration/build.gradle.kts b/instrumented/integration/build.gradle.kts index e85ba14736..d1e949ccc0 100644 --- a/instrumented/integration/build.gradle.kts +++ b/instrumented/integration/build.gradle.kts @@ -8,6 +8,7 @@ import com.datadog.gradle.config.AndroidConfig import com.datadog.gradle.config.depotProxied import com.datadog.gradle.config.java17 import com.datadog.gradle.config.kotlinConfig +import org.gradle.api.artifacts.ModuleDependency plugins { id("ktlint") @@ -134,6 +135,11 @@ dependencies { androidTestImplementation(libs.bundles.integrationTests) androidTestImplementation(libs.okHttpMock) androidTestImplementation(project(":features:dd-sdk-android-trace-internal")) + androidTestImplementation( + (testFixtures(project(":features:dd-sdk-android-rum")) as ModuleDependency).apply { + exclude(mapOf("group" to "dd-sdk-android-timeseries.tools", "module" to "unit")) + } + ) androidTestImplementation(testFixtures(project(":features:dd-sdk-android-trace"))) if (project.hasProperty(com.datadog.gradle.Properties.USE_API21_JAVA_BACKPORT)) { // this is needed to make AssertJ working on APIs <24 diff --git a/instrumented/integration/src/androidTest/kotlin/com/datadog/android/sdk/integration/rum/TimeseriesCollectionTest.kt b/instrumented/integration/src/androidTest/kotlin/com/datadog/android/sdk/integration/rum/TimeseriesCollectionTest.kt new file mode 100644 index 0000000000..17844b0e31 --- /dev/null +++ b/instrumented/integration/src/androidTest/kotlin/com/datadog/android/sdk/integration/rum/TimeseriesCollectionTest.kt @@ -0,0 +1,162 @@ +/* + * 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.sdk.integration.rum + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +import androidx.test.platform.app.InstrumentationRegistry +import com.datadog.android.privacy.TrackingConsent +import com.datadog.android.rum.assertj.TimeseriesCpuEventAssert +import com.datadog.android.rum.assertj.TimeseriesMemoryEventAssert +import com.datadog.android.rum.model.TimeseriesCpuEvent +import com.datadog.android.rum.model.TimeseriesMemoryEvent +import com.datadog.android.sdk.integration.RuntimeConfig +import com.datadog.android.sdk.integration.rum.TimeseriesTrackingPlaygroundActivity.Companion.SAMPLE_INTERVAL_MS +import com.datadog.android.sdk.rules.HandledRequest +import com.datadog.android.sdk.rules.RumMockServerActivityTestRule +import com.datadog.tools.unit.ConditionWatcher +import com.google.gson.JsonObject +import org.assertj.core.api.Assertions.assertThat +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@LargeTest +internal class TimeseriesCollectionTest { + + @get:Rule + val mockServerRule = RumMockServerActivityTestRule( + TimeseriesTrackingPlaygroundActivity::class.java, + keepRequests = true, + trackingConsent = TrackingConsent.GRANTED + ) + + @Test + fun verifyCpuAndMemoryTimeseriesAreCollected() { + // Given + Thread.sleep(FOREGROUND_COLLECTION_DURATION_MS) + + // When + moveActivityToBackground() + val events: List = waitForTimeseriesEvents(expectedCount = TIMESERIES_PIPELINE_COUNT) + + // Then + assertTrue(events.size >= TIMESERIES_PIPELINE_COUNT) + + TimeseriesCpuEventAssert.assertThat(events.cpuEvents().single()) + .hasDataPointsCount(EXPECTED_FOREGROUND_CPU_DATA_POINTS) + + TimeseriesMemoryEventAssert.assertThat(events.memoryEvents().single()) + .hasDataPointsCount(EXPECTED_FOREGROUND_MEMORY_DATA_POINTS) + } + + @Test + fun verifyCollectionFlushesPausesAndResumesAcrossBackgroundTransition() { + // Given + Thread.sleep(FOREGROUND_COLLECTION_DURATION_MS) + + // When + moveActivityToBackground() + val firstForegroundEvents = waitForTimeseriesEvents(expectedCount = TIMESERIES_PIPELINE_COUNT) + Thread.sleep(BACKGROUND_OBSERVATION_DURATION_MS) + val backgroundEvents = timeseriesEvents() + moveActivityToForeground() + Thread.sleep(FOREGROUND_COLLECTION_DURATION_MS) + moveActivityToBackground() + val secondForegroundEvents = waitForTimeseriesEvents(expectedCount = TIMESERIES_PIPELINE_COUNT * 2) + + // Then + assertEquals(TIMESERIES_PIPELINE_COUNT, firstForegroundEvents.size) + TimeseriesCpuEventAssert.assertThat(firstForegroundEvents.cpuEvents().single()) + .hasDataPointsCount(EXPECTED_FOREGROUND_CPU_DATA_POINTS) + TimeseriesMemoryEventAssert.assertThat(firstForegroundEvents.memoryEvents().single()) + .hasDataPointsCount(EXPECTED_FOREGROUND_MEMORY_DATA_POINTS) + assertThat(firstForegroundEvents.size).isEqualTo(backgroundEvents.size) + assertThat(secondForegroundEvents.size).isEqualTo(TIMESERIES_PIPELINE_COUNT * 2) + secondForegroundEvents.memoryEvents().forEach { + TimeseriesMemoryEventAssert.assertThat(it) + .hasDataPointsCount(EXPECTED_FOREGROUND_MEMORY_DATA_POINTS) + } + secondForegroundEvents.cpuEvents().forEach { + TimeseriesCpuEventAssert.assertThat(it) + .hasDataPointsCount(EXPECTED_FOREGROUND_CPU_DATA_POINTS) + } + } + + private fun moveActivityToBackground() { + val instrumentation = InstrumentationRegistry.getInstrumentation() + instrumentation.runOnMainSync { + instrumentation.callActivityOnPause(mockServerRule.activity) + instrumentation.callActivityOnStop(mockServerRule.activity) + } + instrumentation.waitForIdleSync() + } + + private fun moveActivityToForeground() { + val instrumentation = InstrumentationRegistry.getInstrumentation() + instrumentation.runOnMainSync { + instrumentation.callActivityOnStart(mockServerRule.activity) + instrumentation.callActivityOnResume(mockServerRule.activity) + } + instrumentation.waitForIdleSync() + } + + private fun waitForTimeseriesEvents(expectedCount: Int): List { + var events = emptyList() + ConditionWatcher { + events = timeseriesEvents() + assertTrue(events.size >= expectedCount) + true + }.doWait(timeoutMs = RumTest.FINAL_WAIT_MS) + return events + } + + private fun timeseriesEvents(): List = mockServerRule + .getRequests(RuntimeConfig.rumEndpointUrl) + .rumEvents() + .filter { it.get(TYPE_KEY)?.asString == TIMESERIES_TYPE } + + private fun List.rumEvents(): List = flatMap { request -> + request.textBody?.let(::rumPayloadToJsonList).orEmpty() + } + + companion object { + private const val CPU_TIMESERIES_NAME = "cpu" + private const val MEMORY_TIMESERIES_NAME = "memory" + private const val TIMESERIES_TYPE = "timeseries" + private const val TYPE_KEY = "type" + private const val TIMESERIES_KEY = "timeseries" + private const val NAME_KEY = "name" + + // One independent pipeline for each timeseries source: CPU and memory. + private const val TIMESERIES_PIPELINE_COUNT = 2 + private const val ACTIVITY_STOP_DELAY_MS = 200L + private const val FOREGROUND_COLLECTION_DURATION_MS = SAMPLE_INTERVAL_MS * 2 + SAMPLE_INTERVAL_MS / 4 + private const val UPLOAD_GRACE_PERIOD_MS = 500L + private const val BACKGROUND_OBSERVATION_DURATION_MS = + SAMPLE_INTERVAL_MS + UPLOAD_GRACE_PERIOD_MS + + private const val EXPECTED_FOREGROUND_MEMORY_DATA_POINTS = + ((FOREGROUND_COLLECTION_DURATION_MS + ACTIVITY_STOP_DELAY_MS) / SAMPLE_INTERVAL_MS).toInt() + private const val EXPECTED_FOREGROUND_CPU_DATA_POINTS = + EXPECTED_FOREGROUND_MEMORY_DATA_POINTS - 1 + + private val JsonObject.timeseriesName: String? + get() = getAsJsonObject(TIMESERIES_KEY).get(NAME_KEY).asString + + private fun List.filterByName(name: String): List = filter { it.timeseriesName == name } + + private fun List.cpuEvents(): List = + filterByName(CPU_TIMESERIES_NAME).map(TimeseriesCpuEvent::fromJsonObject) + + private fun List.memoryEvents(): List = + filterByName(MEMORY_TIMESERIES_NAME).map(TimeseriesMemoryEvent::fromJsonObject) + } +} diff --git a/instrumented/integration/src/main/AndroidManifest.xml b/instrumented/integration/src/main/AndroidManifest.xml index 2386dcf50c..ef023fc0d1 100644 --- a/instrumented/integration/src/main/AndroidManifest.xml +++ b/instrumented/integration/src/main/AndroidManifest.xml @@ -29,6 +29,9 @@ android:name=".rum.ActivityTrackingPlaygroundActivity" android:label="@string/rum_activity_view_tracking_end_to_end" android:windowSoftInputMode="adjustResize"/> +