diff --git a/detekt_custom_safe_calls_third_party.yml b/detekt_custom_safe_calls_third_party.yml index b44f9ddebc..a6501cd78a 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.RumSessionScopeTimeseries.State?, com.datadog.android.rum.internal.timeseries.RumSessionScopeTimeseries.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.RumSessionScopeTimeseries.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.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?)" @@ -761,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/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/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/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/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 8c995b90e6..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.NoOpTimeseriesFactory -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.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.timeseries.DefaultTimeseriesCollectorFactory +import com.datadog.android.rum.internal.timeseries.NoOpTimeseriesCollectorFactory +import com.datadog.android.rum.internal.timeseries.TimeseriesCollector import com.datadog.android.rum.internal.tracking.JetpackViewAttributesProvider import com.datadog.android.rum.internal.tracking.NoOpInteractionPredicate import com.datadog.android.rum.internal.tracking.NoOpUserActionTrackingStrategy @@ -200,7 +194,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 @@ -302,11 +296,16 @@ internal class RumFeature( sessionListener = configuration.sessionListener - configuration.timeseriesConfiguration?.let { configuration -> - timeseriesFactory = 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 ) } @@ -375,8 +374,8 @@ internal class RumFeature( unregisterTrackingStrategies(appContext) - timeseriesFactory = NoOpTimeseriesFactory() - (GlobalRumMonitor.get(sdkCore) as? DatadogRumMonitor)?.stopActiveTimeseries() + timeseriesCollectorFactory = NoOpTimeseriesCollectorFactory() + (GlobalRumMonitor.get(sdkCore) as? DatadogRumMonitor)?.stopTimeseries() dataWriter = NoOpDataWriter() @@ -452,68 +451,6 @@ internal class RumFeature( ) } - @Suppress("LongMethod") - internal fun createTimeseriesCollectingFactory( - configuration: TimeseriesConfiguration, - totalRamBytes: Long, - insightsCollector: InsightsCollector - ): Timeseries.Factory = RumSessionScopeTimeseriesFactory( - internalLogger = sdkCore.internalLogger, - collectInBackground = configuration.collectInBackground, - 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) { @@ -975,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/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/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 8d5396e559..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 @@ -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,11 @@ internal class RumSessionScope( } } - timeseries.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,17 +238,18 @@ internal class RumSessionScope( } private fun startTimeseries() { - timeseries = timeseriesFactory.create( - sessionId = sessionId, - applicationId = parentScope.getRumContext().applicationId, - sessionType = getRumContext().resolveSessionType(rumSessionTypeOverride) + val rumContext = getActiveRumContext() + timeseriesCollector = timeseriesCollectorFactory.create( + rumContext = rumContext, + sessionType = rumContext.resolveSessionType(rumSessionTypeOverride), + customAttributes = ::getCustomAttributes ) - 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/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/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/DefaultTimeseriesCollector.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt new file mode 100644 index 0000000000..e991999878 --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollector.kt @@ -0,0 +1,205 @@ +/* + * 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 + +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 + +internal class DefaultTimeseriesCollector( + private val internalLogger: InternalLogger, + internal val pipelines: List>, + internal val scheduledExecutorService: ScheduledExecutorService, + @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 = rumContext.viewType.isForeground)?.let { generation -> scheduleSampling(generation) } + } + + @WorkerThread + override fun onSessionStop() { + cancelSuspension() + if (state.set(false) != null) { + flushPipelines(lastForegroundRumContext) + } + } + + @WorkerThread + 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 + + rumContext = newRumContext + if (newViewType.isForeground) lastForegroundRumContext = newRumContext + + if (isLeaveForeground) { + scheduleStop(state.currentGeneration) + } else if (isEnterForeground) { + scheduleSampling(generation = state.startGeneration()) + } + } + + // endregion + + //region SAMPLING + + private fun scheduleSampling(generation: Int) { + cancelSuspension() + pipelines.forEach { pipeline -> scheduledExecutorService.schedulePipeline(pipeline, generation) } + } + + private fun ScheduledExecutorService.schedulePipeline( + pipeline: Pipeline<*>, + generation: Int + ) { + scheduleSafe( + TIMESERIES_OPERATION_NAME, + pipeline.intervalMs, + TimeUnit.MILLISECONDS, + internalLogger + ) { + if (!state.isGenerationActive(generation)) return@scheduleSafe + try { + val currentRumContext = rumContext + if (currentRumContext.viewType.isForeground) { + pipeline.execute(currentRumContext) + } + } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { + internalLogger.log( + level = InternalLogger.Level.ERROR, + targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), + messageBuilder = { ERROR_SAMPLING_FAILED }, + throwable = t + ) + } finally { + if (state.isGenerationActive(generation)) schedulePipeline(pipeline, generation) + } + } + } + + @WorkerThread + private fun flushPipelines(rumContext: RumContext) { + pipelines.forEach { pipeline -> + try { + pipeline.flush(rumContext) + } 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 (!rumContext.viewType.isForeground && state.stopGeneration(stopRequestGeneration)) { + flushPipelines(lastForegroundRumContext) + } + } + } + + private fun cancelSuspension() { + recentSuspension?.cancel(false) + recentSuspension = null + } + + // endregion + + internal companion object { + 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 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 + RumViewType.BACKGROUND -> false + 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 new file mode 100644 index 0000000000..f8018c0105 --- /dev/null +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactory.kt @@ -0,0 +1,117 @@ +/* + * 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 + +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.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 sdkCore: FeatureSdkCore, + private val configuration: TimeseriesConfiguration, + private val scheduledExecutorService: ScheduledExecutorService, + 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( + sessionType: RumSessionType, + 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/RumSessionScopeTimeseries.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseries.kt deleted file mode 100644 index 1fc4a36d92..0000000000 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseries.kt +++ /dev/null @@ -1,139 +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 - -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.scope.RumViewType -import java.util.concurrent.ScheduledExecutorService -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): - * - 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. - * - * Background sampling: - * - When [collectInBackground] is `false`, [onViewTypeUpdate] pauses sampling on leaving foreground - * and resumes it on returning to foreground. - * - * 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. - */ -internal class RumSessionScopeTimeseries( - private val internalLogger: InternalLogger, - internal val pipelines: List>, - private val collectInBackground: Boolean, - internal val scheduledExecutorService: ScheduledExecutorService -) : Timeseries { - - 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) - - @Volatile - private var currentViewType: RumViewType? = null - - @WorkerThread - override fun onSessionStart() { - if (state.compareAndSet(State.IDLE, State.RUNNING)) { - startSampling() - } - } - - @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 - ) - } - } - } - } - - @WorkerThread - override fun onViewTypeUpdate(newViewType: RumViewType) { - if (newViewType == currentViewType) return - val isEnterForeground = !currentViewType.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) - } - } - } - - private fun startSampling() { - val generation = currentGeneration.incrementAndGet() - pipelines.forEach { schedulePipeline(it, generation) } - } - - private fun schedulePipeline(pipeline: Pipeline<*>, generation: Int) { - scheduledExecutorService.scheduleSafe( - OPERATION_NAME, - pipeline.intervalMs, - TimeUnit.MILLISECONDS, - internalLogger - ) { - if (!isActive(generation)) return@scheduleSafe - try { - synchronized(pipeline) { - if (isActive(generation)) pipeline.execute() - } - } catch (@Suppress("TooGenericExceptionCaught") t: Throwable) { - internalLogger.log( - level = InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - messageBuilder = { ERROR_SAMPLING_FAILED }, - throwable = t - ) - } finally { - if (isActive(generation)) schedulePipeline(pipeline, generation) - } - } - } - - private fun isActive(generation: Int): Boolean = - state.get() == State.RUNNING && currentGeneration.get() == generation - - internal companion object { - const val OPERATION_NAME = "Timeseries sampling" - const val ERROR_SAMPLING_FAILED = "Timeseries sampling iteration failed; rescheduling next sample." - const val ERROR_FLUSH_FAILED = "Timeseries flush on session stop failed." - val RumViewType?.isForeground: Boolean - get() = when (this) { - RumViewType.FOREGROUND, RumViewType.APPLICATION_LAUNCH -> true - RumViewType.BACKGROUND -> false - RumViewType.NONE -> false - null -> false - } - } -} 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/RumSessionScopeTimeseriesFactory.kt deleted file mode 100644 index 9e42560294..0000000000 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactory.kt +++ /dev/null @@ -1,31 +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 - -import com.datadog.android.api.InternalLogger -import com.datadog.android.rum.RumSessionType -import java.util.concurrent.ScheduledExecutorService - -internal class RumSessionScopeTimeseriesFactory( - private val internalLogger: InternalLogger, - private val collectInBackground: Boolean, - private val scheduledExecutorService: ScheduledExecutorService, - private val pipelinesProvider: ( - applicationId: String, - sessionId: String, - sessionType: RumSessionType - ) -> List> -) : Timeseries.Factory { - - override fun create(applicationId: String, sessionId: String, sessionType: RumSessionType) = - RumSessionScopeTimeseries( - internalLogger = internalLogger, - collectInBackground = collectInBackground, - scheduledExecutorService = scheduledExecutorService, - pipelines = pipelinesProvider(applicationId, sessionId, sessionType) - ) -} 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 61% 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..40c8ba7a1d 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 @@ -7,17 +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 Timeseries { +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): Timeseries + fun create( + sessionType: RumSessionType, + 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 2b9e762483..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,9 +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 collectInBackground: Boolean + internal val enabledTypes: Set ) { /** @@ -28,45 +22,25 @@ class TimeseriesConfiguration internal constructor( @ExperimentalRumApi class Builder { - private var bufferSize: Int = DEFAULT_BUFFER_SIZE - private var intervalMs: Long = DEFAULT_INTERVAL_MS - private var collectInBackground: Boolean = false + @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 - } - - /** - * 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 + 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, - collectInBackground = collectInBackground + enabledTypes = enabledTypes ) } @@ -81,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 3778de151e..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,14 +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.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.RumSessionScopeTimeseries -import com.datadog.android.rum.internal.timeseries.Timeseries +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 @@ -859,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).stopActiveTimeseries() + 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 RumSessionScopeTimeseries) - 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 RumSessionScopeTimeseries) - 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 @@ -1915,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): Timeseries = - testedFeature - .createTimeseriesCollectingFactory( - TimeseriesConfiguration.Builder().build(), - totalRamBytes, - testedFeature.configuration.insightsCollector - ) - .create(fakeApplicationId.toString(), sessionId, RumSessionType.USER) - 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 f2e1e67b81..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.Timeseries +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 mockTimeseriesFactory: Timeseries.Factory - - @Mock - lateinit var mockTimeseries: Timeseries - @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(mockTimeseriesFactory.create(any(), any(), any())) doReturn mockTimeseries testedScope = RumApplicationScope( applicationId = fakeApplicationId, sdkCore = rumMonitor.mockSdkCore, @@ -224,7 +217,7 @@ internal class RumApplicationScopeAttributePropagationTest { rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesFactory = mockTimeseriesFactory + 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 4547c169ce..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 @@ -30,7 +31,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 +140,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 +186,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 +210,7 @@ internal class RumApplicationScopeTest { rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, heatmapIdentifierRegistry = null, - timeseriesFactory = mockTimeseriesFactory + timeseriesCollectorFactory = mockCollectorFactory ) } @@ -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(mockTimeseriesFactory).create(eq(fakeApplicationId), 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(mockTimeseriesFactory, times(2)).create(eq(fakeApplicationId), 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 df8b816ce6..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.Timeseries 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 mockTimeseriesFactory: Timeseries.Factory - - @Mock - lateinit var mockTimeseries: Timeseries - 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(mockTimeseriesFactory.create(any(), any(), any())) doReturn mockTimeseries testedScope = RumSessionScope( parentScope = mockParentScope, sdkCore = mockSdkCore, @@ -197,8 +189,7 @@ internal class RumSessionScopeAttributePropagationTest { displayInfoProvider = mockDisplayInfoProvider, rumSessionScopeStartupManagerFactory = mock(), insightsCollector = mockInsightsCollector, - heatmapIdentifierRegistry = null, - timeseriesFactory = mockTimeseriesFactory + 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 99bae97d64..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 @@ -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 @@ -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 @@ -197,10 +195,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 +228,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 @@ -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(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) // When testedScope.handleEvent( @@ -1869,167 +1868,78 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseriesFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - fakeRumSessionType ?: RumSessionType.USER - ) - verify(mockTimeseries).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(timeseriesFactory = mockTimeseriesFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockTimeseriesFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - RumSessionType.USER - ) + val rumContextCaptor = argumentCaptor() + verify(mockCollectorFactory).create(any(), rumContextCaptor.capture(), any()) + assertThat(rumContextCaptor.firstValue).isEqualTo(testedScope.getRumContext()) + verify(mockCollector).onSessionStart() } @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 - ) { - // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = fakeResultId) - fakeRumSessionType = null - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + 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(mockTimeseriesFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - RumSessionType.SYNTHETICS - ) + // 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 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 - ) { + fun `M pass active view context to factory W renewSession { foreground view active }`(forge: Forge) { // Given - fakeParentContext = fakeParentContext.copy(syntheticsTestId = fakeTestId, syntheticsResultId = fakeResultId) - val expectedSessionType = forge.aValueFrom(RumSessionType::class.java) - fakeRumSessionType = expectedSessionType - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + 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(mockTimeseriesFactory).create( - fakeParentContext.applicationId, - testedScope.sessionId, - expectedSessionType - ) + // 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 { 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(timeseriesFactory = mockTimeseriesFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(expectedSessionType)) - } - - @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(timeseriesFactory = mockTimeseriesFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) - } - - @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(timeseriesFactory = mockTimeseriesFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) - } - - @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(timeseriesFactory = mockTimeseriesFactory) - - // When - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) - } - - @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(timeseriesFactory = mockTimeseriesFactory) + fakeParentContext = fakeParentContext.copy( + syntheticsTestId = fakeSyntheticsTestId, + syntheticsResultId = fakeSyntheticsResultId + ) + initializeTestedScope( + collectorFactory = mockCollectorFactory, + rumSessionTypeOverride = fakeSessionTypeOverride + ) // When testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) // Then - verify(mockTimeseriesFactory).create(any(), any(), eq(RumSessionType.USER)) + 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(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) // When testedScope.handleEvent( @@ -2040,40 +1950,39 @@ 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) { + fun `M stop previous and feed fresh timeseries W renewSession { another tracked session }`(forge: Forge) { // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) - 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(mockTimeseries).onSessionStop() - verify(mockTimeseriesFactory, times(2)).create(any(), any(), any()) - verify(mockTimeseries, 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, timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(backgroundTrackingEnabled = false, collectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2087,13 +1996,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(collectorFactory = mockCollectorFactory) testedScope.handleEvent( forge.startViewEvent(), fakeDatadogContext, @@ -2110,126 +2019,58 @@ internal class RumSessionScopeTest { ) // Then - verify(mockTimeseries).onSessionStop() - } - - @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(mockTimeseries, mockTimeseriesFactory) + verify(mockCollector).onSessionStop() } @Test - fun `M notify timeseries of view type W handleEvent`(forge: Forge) { - // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) - 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(mockTimeseries, 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, - timeseriesFactory = mockTimeseriesFactory + collectorFactory = mockCollectorFactory ) + val fakeStartViewEvent = forge.startViewEvent() // When testedScope.handleEvent( - forge.startViewEvent(), + fakeStartViewEvent, fakeDatadogContext, mockEventWriteScope, mockWriter ) // Then - verify(mockTimeseries).onViewTypeUpdate(RumViewType.FOREGROUND) - verify(mockTimeseries, 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) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // When - testedScope.handleEvent(forge.addErrorEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(mockTimeseries, 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(timeseriesFactory = mockTimeseriesFactory) - 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) - } - - @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(timeseriesFactory = mockTimeseriesFactory) - 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(mockTimeseries) - inOrder.verify(mockTimeseries, times(2)).onSessionStart() - inOrder.verify(mockTimeseries).onViewTypeUpdate(RumViewType.FOREGROUND) + 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 stop previous timeseries W renewSession { ResetSession renews tracked session }`(forge: Forge) { + fun `M stop previous timeseries W handleEvent { ResetSession }`(forge: Forge) { // Given - initializeTestedScope(timeseriesFactory = mockTimeseriesFactory) + initializeTestedScope(collectorFactory = mockCollectorFactory) testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - val firstTimeseries = mockTimeseries - val secondTimeseries: Timeseries = mock() - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn secondTimeseries + val firstTimeseries = mockCollector + val secondCollector: TimeseriesCollector = mock() + whenever(mockCollectorFactory.create(any(), any(), any())) doReturn secondCollector // When testedScope.handleEvent( @@ -2240,33 +2081,15 @@ internal class RumSessionScopeTest { ) // Then - verify(firstTimeseries).onSessionStart() verify(firstTimeseries).onSessionStop() - verify(secondTimeseries).onSessionStart() + 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, timeseriesFactory = mockTimeseriesFactory) - testedScope.handleEvent(forge.startViewEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - val firstTimeseries = mockTimeseries - val secondTimeseries: Timeseries = mock() - whenever(mockTimeseriesFactory.create(any(), any(), any())) doReturn secondTimeseries - advanceTimeByMs(TEST_INACTIVITY_MS) - testedScope.handleEvent(mock(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // When - testedScope.handleEvent(forge.startActionEvent(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - verify(firstTimeseries).onSessionStart() - verify(firstTimeseries).onSessionStop() - verify(secondTimeseries).onSessionStart() - } + initializeTestedScope(collectorFactory = mockCollectorFactory) - @Test - fun `M not stop timeseries W handleEvent { StopSession, no tracked session }`() { // When testedScope.handleEvent( RumRawEvent.StopSession(eventTime = currentFakeTime()), @@ -2276,7 +2099,8 @@ internal class RumSessionScopeTest { ) // Then - verifyNoInteractions(mockTimeseries) + verify(mockCollectorFactory, never()).create(any(), any(), any()) + verifyNoInteractions(mockCollector) } // endregion @@ -2298,7 +2122,8 @@ internal class RumSessionScopeTest { sessionSampler: Sampler = mockSessionSampler, withMockChildScope: Boolean = true, backgroundTrackingEnabled: Boolean? = null, - timeseriesFactory: Timeseries.Factory = NoOpTimeseriesFactory() + collectorFactory: TimeseriesCollector.Factory = NoOpTimeseriesCollectorFactory(), + rumSessionTypeOverride: RumSessionType? = fakeRumSessionType ) { testedScope = RumSessionScope( parentScope = mockParentScope, @@ -2319,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, - timeseriesFactory = timeseriesFactory + timeseriesCollectorFactory = collectorFactory ) if (withMockChildScope) { @@ -2345,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/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/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 new file mode 100644 index 0000000000..f46b637ec8 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorFactoryTest.kt @@ -0,0 +1,287 @@ +/* + * 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 + +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.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 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.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.verifyNoInteractions +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness +import java.util.concurrent.ScheduledExecutorService + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(Configurator::class) +@OptIn(ExperimentalRumApi::class) +internal class DefaultTimeseriesCollectorFactoryTest { + + @Mock + lateinit var mockSdkCore: FeatureSdkCore + + @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 use default sampling settings 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) + assertThat(timeseries.pipelines.map { it.intervalMs }) + .containsOnly(TimeseriesConfiguration.DEFAULT_INTERVAL_MS) + assertThat( + timeseries.pipelines.map { pipeline -> + pipeline.getFieldValue, Pipeline<*>>("buffer") + .getFieldValue>("size") + } + ).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(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 + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).hasSize(1) + val eventFactory = timeseries.pipelines.single() + .getFieldValue>("eventFactory") + assertThat(eventFactory).isInstanceOf(CpuEventFactory::class.java) + verifyNoInteractions(mockInternalLogger) + } + + @Test + fun `M build only memory pipeline W create() { configuration collects only memory }`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long + ) { + // Given + val fakeConfiguration = TimeseriesConfiguration.Builder() + .collectOnly(TimeseriesType.MEMORY) + .build() + val testedFactory = createFactory(fakeTotalRamBytes, fakeConfiguration) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) + + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).hasSize(1) + val eventFactory = timeseries.pipelines.single() + .getFieldValue>("eventFactory") + assertThat(eventFactory).isInstanceOf(MemoryEventFactory::class.java) + } + + @Test + fun `M build no pipelines W create() { configuration collects no types }`( + @LongForgery(min = 1L) fakeTotalRamBytes: Long + ) { + // Given + val fakeConfiguration = TimeseriesConfiguration.Builder() + .collectOnly(*emptyArray()) + .build() + val testedFactory = createFactory(fakeTotalRamBytes, fakeConfiguration) + + // When + val timeseries = testedFactory.create(fakeSessionType, fakeRumContext, fakeCustomAttributes) + + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.pipelines).isEmpty() + } + + @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) + + // Then + check(timeseries is DefaultTimeseriesCollector) + assertThat(timeseries.scheduledExecutorService).isSameAs(mockExecutor) + assertThat( + timeseries.getFieldValue("rumContext") + ).isSameAs(fakeRumContext) + } + + @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 new file mode 100644 index 0000000000..6f44704c65 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/DefaultTimeseriesCollectorTest.kt @@ -0,0 +1,826 @@ +/* + * 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 + +import com.datadog.android.api.InternalLogger +import com.datadog.android.api.context.DatadogContext +import com.datadog.android.api.feature.EventWriteScope +import com.datadog.android.api.feature.Feature +import com.datadog.android.api.feature.FeatureScope +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.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 +import fr.xgouchet.elmyr.junit5.ForgeExtension +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 +import org.mockito.kotlin.eq +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.UUID +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.ScheduledFuture +import java.util.concurrent.TimeUnit + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(Configurator::class) +internal class DefaultTimeseriesCollectorTest { + + private lateinit var testedTimeseries: DefaultTimeseriesCollector + + @Mock + lateinit var mockDataWriter: DataWriter + + @Mock + lateinit var mockInternalLogger: InternalLogger + + @Mock + lateinit var mockSdkCore: FeatureSdkCore + + @Mock + lateinit var mockRumFeatureScope: FeatureScope + + @Mock + lateinit var mockEventWriteScope: EventWriteScope + + @Mock + lateinit var mockEventBatchWriter: EventBatchWriter + + @Mock + lateinit var mockDatadogContext: DatadogContext + + @Mock + lateinit var mockExecutor: ScheduledExecutorService + + @Mock + lateinit var mockScheduledFuture: ScheduledFuture<*> + + @Mock + lateinit var mockReaderA: DataPointsReader + + @Mock + lateinit var mockReaderB: DataPointsReader + + @Mock + lateinit var mockEventFactoryA: EventFactory + + @Mock + lateinit var mockEventFactoryB: EventFactory + + private lateinit var bufferA: Buffer + private lateinit var bufferB: Buffer + + private lateinit var pipelineA: Pipeline + private lateinit var pipelineB: Pipeline + + @LongForgery(min = 1_000L, max = 60_000L) + var fakeIntervalAMs: Long = 0L + + @LongForgery(min = 60_001L, max = 120_000L) + var fakeIntervalBMs: Long = 0L + + @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 + whenever(mockReaderB.intervalMs) doReturn fakeIntervalBMs + 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 -> + inv.getArgument<(DatadogContext, EventWriteScope) -> Unit>(inv.arguments.lastIndex) + .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, mockEventFactoryA, mockDataWriter, { emptyMap() }) + pipelineB = Pipeline(mockSdkCore, mockReaderB, bufferB, mockEventFactoryB, mockDataWriter, { emptyMap() }) + + testedTimeseries = createTimeseries(RumViewType.FOREGROUND) + } + + @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() + + // Then + verify(mockExecutor).schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + 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 schedule W onRumContextUpdate() { none to background }`() { + // Given + testedTimeseries = createTimeseries(RumViewType.NONE) + testedTimeseries.onSessionStart() + + // When + 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(mockExecutor).schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + verify(mockExecutor).schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) + } + + @Test + fun `M not shut down shared executor W onSessionStop()`() { + // Given + testedTimeseries.onSessionStart() + + // When + testedTimeseries.onSessionStop() + + // Then — executor is owned by the SDK core and reused across components + verify(mockExecutor, never()).shutdown() + verify(mockExecutor, never()).shutdownNow() + } + + @Test + fun `M not write events W onSessionStop() { nothing sampled }`() { + // Given + testedTimeseries.onSessionStart() + + // When + testedTimeseries.onSessionStop() + + // Then + verify(mockDataWriter, never()).write(any(), any(), any()) + } + + @Test + 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") } + val mockBuffer = mock>() + whenever(mockBuffer.drain()) doThrow fakeError + whenever(mockReaderB.read()) doReturn forge.getForgery>() + 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() + captureScheduledRunnableForInterval(fakeIntervalBMs).run() // buffers one sample for pipeline B + + // When + testedTimeseries.onSessionStop() + + // Then + mockInternalLogger.verifyLog( + InternalLogger.Level.ERROR, + targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), + DefaultTimeseriesCollector.ERROR_FLUSH_FAILED, + fakeError + ) + verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) + } + + @Test + 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(mockEventFactoryA.create(any(), any(), any(), any())) doReturn fakeJson + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + runnableA.run() + + // When + testedTimeseries.onSessionStop() + + // Then + verify(mockEventFactoryA).create(any(), any(), any(), any()) + verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) + } + + @Test + fun `M write batch W sample tick { buffer reaches capacity }`(forge: Forge) { + // Given + val fakePoint = forge.getForgery>() + val fakeDataPoints = List(fakeBufferSize) { fakePoint } + val fakeJson = JsonObject().apply { addProperty("a", "1") } + whenever(mockReaderA.read()) doReturn fakePoint + whenever(mockEventFactoryA.create(any(), any(), eq(fakeDataPoints), any())) doReturn fakeJson + + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + repeat(fakeBufferSize) { runnableA.run() } + + // Then + verify(mockEventFactoryA).create( + eq(mockDatadogContext), + eq(fakeRumContextOf(RumViewType.FOREGROUND)), + eq(fakeDataPoints), + any() + ) + verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) + } + + @Test + fun `M reschedule sample W sample tick runs`(forge: Forge) { + // Given + whenever(mockReaderA.read()) doReturn forge.getForgery>() + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + runnableA.run() + + // Then - 1 schedule from start() + 1 reschedule from sample tick + verify(mockExecutor, times(2)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + } + + @Test + fun `M not write events W sample tick { buffer not full }`(forge: Forge) { + // Given + whenever(mockReaderA.read()) doReturn forge.getForgery>() + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + repeat(fakeBufferSize - 1) { runnableA.run() } + + // Then + verify(mockEventFactoryA, never()).create(any(), any(), any(), any()) + verify(mockDataWriter, never()).write(any(), any(), any()) + } + + @Test + fun `M not start twice W onSessionStart() { called twice }`() { + // When + testedTimeseries.onSessionStart() + testedTimeseries.onSessionStart() + + // Then — executor.schedule called exactly once per pipeline (not doubled) + verify(mockExecutor).schedule( + any(), + eq(fakeIntervalAMs), + eq(TimeUnit.MILLISECONDS) + ) + verify(mockExecutor).schedule( + any(), + eq(fakeIntervalBMs), + eq(TimeUnit.MILLISECONDS) + ) + } + + @Test + fun `M flush only once W onSessionStop() { called twice }`() { + // Given + val mockBuffer = mock>() + testedTimeseries = createTimeseriesWithBuffer(mockBuffer) + testedTimeseries.onSessionStart() + + // When + testedTimeseries.onSessionStop() + testedTimeseries.onSessionStop() + + // Then — the second call sees the state already STOPPED and never reaches the pipelines + verify(mockBuffer).drain() + } + + @Test + fun `M log error and reschedule 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 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'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>() + testedTimeseries = createTimeseriesWithBuffer(mockBuffer) + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + runnableA.run() + + // Then + 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 { 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("event factory failure") + whenever(mockReaderA.read()) doReturn forge.getForgery>() + whenever(mockEventFactoryA.create(any(), any(), any(), any())) doThrow fakeError + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + repeat(fakeBufferSize) { runnableA.run() } + + // Then + // 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 event creation failed", + fakeError + ) + verify(mockDataWriter, never()).write(any(), any(), any()) + verify(mockExecutor, times(fakeBufferSize + 1)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + } + + @Test + fun `M log error and reschedule W sample tick { write context resolution throws }`(forge: Forge) { + // Given — withWriteContext() itself throws (context/scope resolution failure), outside + // Pipeline's own try/catch, so it propagates up to the sampling try/catch. + val fakeError = RuntimeException("write context resolution failure") + whenever(mockReaderA.read()) doReturn forge.getForgery>() + whenever(mockRumFeatureScope.withWriteContext(any(), any())) doThrow fakeError + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + repeat(fakeBufferSize) { runnableA.run() } + + // Then + mockInternalLogger.verifyLog( + InternalLogger.Level.ERROR, + targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), + DefaultTimeseriesCollector.ERROR_SAMPLING_FAILED, + fakeError + ) + verify(mockExecutor, times(fakeBufferSize + 1)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + } + + @Test + 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() + + // When + runnableA.run() + + // Then — sample skipped AND no additional schedule after the one from start() + verify(mockReaderA, never()).read() + verify(mockExecutor).schedule( + any(), + eq(fakeIntervalAMs), + eq(TimeUnit.MILLISECONDS) + ) + } + + @ParameterizedTest + @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.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(mockEventFactoryA) + verifyNoInteractions(mockDataWriter) + } + + @Test + fun `M use updated context W sample tick fills buffer { foreground view changed }`(forge: Forge) { + // Given + 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() + testedTimeseries.onRumContextUpdate(fakeNextContext) + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + + // When + repeat(fakeBufferSize) { runnableA.run() } + + // Then + 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 with last foreground context W pending suspend fires { left foreground }`( + nextViewType: RumViewType, + forge: Forge + ) { + // Given + val fakeSample = forge.getForgery>() + val fakeJson = JsonObject().apply { addProperty("k", "v") } + whenever(mockReaderA.read()) doReturn fakeSample + 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.onRumContextUpdate(fakeRumContextOf(nextViewType)) + + // When + runScheduledSuspend() + + // 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) + verify(mockEventFactoryB, never()).create(any(), any(), any(), any()) + } + + @ParameterizedTest + @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(mockEventFactoryA.create(any(), any(), any(), any())) doReturn JsonObject() + testedTimeseries.onSessionStart() + captureScheduledRunnableForInterval(fakeIntervalAMs).run() // buffers one sample for pipeline A + testedTimeseries.onRumContextUpdate(fakeRumContextOf(nextViewType)) + + // When — the session is stopped before the pending suspend had a chance to flush + testedTimeseries.onSessionStop() + + // 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 W onRumContextUpdate() { 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.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + + // 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"] + ) + fun `M skip sample and reschedule W sample tick { foreground exit is pending }`( + nextViewType: RumViewType + ) { + // Given + testedTimeseries.onSessionStart() + val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(nextViewType)) + + // When + runnableA.run() + + // Then + verify(mockReaderA, never()).read() + verify(mockExecutor, times(2)) + .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) + } + + @Test + fun `M keep sampling chain W stale suspend fires { foreground re-entered then left }`() { + // Given + testedTimeseries.onSessionStart() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) + val staleSuspend = captureScheduledSuspendRunnable() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) + val currentRunnableA = captureLastScheduledRunnableForInterval(fakeIntervalAMs) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + + // When + staleSuspend.run() + currentRunnableA.run() + + // Then + 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 cancel pending suspend W onRumContextUpdate() { foreground re-entered }`() { + // Given + testedTimeseries.onSessionStart() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) + + // When + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) + + // Then + verify(mockScheduledFuture).cancel(false) + } + + @Test + fun `M schedule suspend once W onRumContextUpdate() { repeated non-foreground updates }`() { + // Given + testedTimeseries.onSessionStart() + + // When + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.NONE)) + + // Then + verify(mockExecutor).schedule( + any(), + eq(DefaultTimeseriesCollector.SUSPEND_DELAY_MS), + eq(TimeUnit.MILLISECONDS) + ) + } + + @Test + fun `M not flush twice W pending suspend fires { session already stopped }`() { + // Given + val mockBuffer = mock>() + testedTimeseries = createTimeseriesWithBuffer(mockBuffer) + testedTimeseries.onSessionStart() + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + testedTimeseries.onSessionStop() // drains the buffer synchronously + + // When + runScheduledSuspend() + + // Then — the pending suspend loses the CAS against STOPPED and does nothing + verify(mockBuffer).drain() + } + + @Test + fun `M resume scheduling W onRumContextUpdate() { background to foreground }`() { + // Given — the deferred suspend fired, so the next tick dies without rescheduling + testedTimeseries.onSessionStart() + 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.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) + + // 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 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.onRumContextUpdate(fakeRumContextOf(RumViewType.BACKGROUND)) + runScheduledSuspend() + val staleRunnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) + // Resume: state = RUNNING, generation = 2; A and B each get a fresh schedule + testedTimeseries.onRumContextUpdate(fakeRumContextOf(RumViewType.FOREGROUND)) + + // 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 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 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/RumSessionScopeTimeseriesFactoryTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactoryTest.kt deleted file mode 100644 index 16c418b19a..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesFactoryTest.kt +++ /dev/null @@ -1,107 +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 - -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.timeseries.provider.DataPointsReader -import com.datadog.android.rum.internal.timeseries.serializer.JsonSerializer -import com.datadog.android.rum.utils.forge.Configurator -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.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.mock -import org.mockito.kotlin.verify -import org.mockito.kotlin.whenever -import org.mockito.quality.Strictness -import java.util.concurrent.ScheduledExecutorService - -@Extensions( - ExtendWith(MockitoExtension::class), - ExtendWith(ForgeExtension::class) -) -@MockitoSettings(strictness = Strictness.LENIENT) -@ForgeConfiguration(Configurator::class) -internal class RumSessionScopeTimeseriesFactoryTest { - - @Mock - lateinit var mockSdkCore: FeatureSdkCore - - @Mock - lateinit var mockInternalLogger: InternalLogger - - @Mock - lateinit var mockWriter: DataWriter - - @Mock - lateinit var mockExecutor: ScheduledExecutorService - - @Test - fun `M build RumSessionScopeTimeseries with provided pipelines W create()`( - @StringForgery fakeSessionId: String, - @StringForgery fakeApplicationId: String - ) { - // 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 = RumSessionScopeTimeseriesFactory( - internalLogger = mockInternalLogger, - collectInBackground = false, - scheduledExecutorService = mockExecutor, - pipelinesProvider = provider - ) - - // When - val timeseries = testedFactory.create(fakeSessionId, fakeApplicationId, fakeSessionType) - - // Then - verify(provider).invoke(fakeSessionId, fakeApplicationId, fakeSessionType) - assertThat(timeseries.scheduledExecutorService).isSameAs(mockExecutor) - } - - @Test - fun `M propagate collectInBackground flag W create()`( - @StringForgery fakeSessionId: String, - @StringForgery fakeApplicationId: String - ) { - // Given - val emptyProvider: (String, String, RumSessionType) -> List> = { _, _, _ -> emptyList() } - val testedFactory = RumSessionScopeTimeseriesFactory( - internalLogger = mockInternalLogger, - collectInBackground = true, - scheduledExecutorService = mockExecutor, - pipelinesProvider = emptyProvider - ) - - // When / Then - assertDoesNotThrow { - testedFactory.create(fakeSessionId, fakeApplicationId, RumSessionType.USER) - } - } - - private fun mockPipeline(): Pipeline<*> { - val reader = mock>() - val serializer = mock>() - return Pipeline(mockSdkCore, reader, Buffer(1), serializer, mockWriter, mockInternalLogger) - } -} 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/RumSessionScopeTimeseriesTest.kt deleted file mode 100644 index 4429538af9..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/RumSessionScopeTimeseriesTest.kt +++ /dev/null @@ -1,605 +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 - -import com.datadog.android.api.InternalLogger -import com.datadog.android.api.context.DatadogContext -import com.datadog.android.api.feature.EventWriteScope -import com.datadog.android.api.feature.Feature -import com.datadog.android.api.feature.FeatureScope -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.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 -import com.datadog.android.utils.verifyLog -import com.google.gson.JsonObject -import fr.xgouchet.elmyr.Forge -import fr.xgouchet.elmyr.annotation.IntForgery -import fr.xgouchet.elmyr.annotation.LongForgery -import fr.xgouchet.elmyr.junit5.ForgeConfiguration -import fr.xgouchet.elmyr.junit5.ForgeExtension -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.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.doAnswer -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.doThrow -import org.mockito.kotlin.eq -import org.mockito.kotlin.mock -import org.mockito.kotlin.never -import org.mockito.kotlin.times -import org.mockito.kotlin.verify -import org.mockito.kotlin.whenever -import org.mockito.quality.Strictness -import java.util.concurrent.ScheduledExecutorService -import java.util.concurrent.ScheduledFuture -import java.util.concurrent.TimeUnit - -@Extensions( - ExtendWith(MockitoExtension::class), - ExtendWith(ForgeExtension::class) -) -@MockitoSettings(strictness = Strictness.LENIENT) -@ForgeConfiguration(Configurator::class) -internal class RumSessionScopeTimeseriesTest { - - private lateinit var testedTimeseries: RumSessionScopeTimeseries - - @Mock - lateinit var mockDataWriter: DataWriter - - @Mock - lateinit var mockInternalLogger: InternalLogger - - @Mock - lateinit var mockSdkCore: FeatureSdkCore - - @Mock - lateinit var mockRumFeatureScope: FeatureScope - - @Mock - lateinit var mockEventWriteScope: EventWriteScope - - @Mock - lateinit var mockEventBatchWriter: EventBatchWriter - - @Mock - lateinit var mockExecutor: ScheduledExecutorService - - @Mock - lateinit var mockReaderA: DataPointsReader - - @Mock - lateinit var mockReaderB: DataPointsReader - - @Mock - lateinit var mockSerializerA: JsonSerializer - - @Mock - lateinit var mockSerializerB: JsonSerializer - - private lateinit var bufferA: Buffer - private lateinit var bufferB: Buffer - - private lateinit var pipelineA: Pipeline - private lateinit var pipelineB: Pipeline - - @LongForgery(min = 1L, max = 60_000L) - var fakeIntervalAMs: Long = 0L - - @LongForgery(min = 60_001L, max = 120_000L) - var fakeIntervalBMs: Long = 0L - - @IntForgery(min = 2, max = 16) - var fakeBufferSize: Int = 0 - - @BeforeEach - fun `set up`() { - whenever(mockReaderA.intervalMs) doReturn fakeIntervalAMs - whenever(mockReaderB.intervalMs) doReturn fakeIntervalBMs - whenever(mockExecutor.schedule(any(), any(), any())) doReturn mock>() - whenever(mockSdkCore.internalLogger) doReturn mockInternalLogger - 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) - } - whenever(mockEventWriteScope.invoke(any())) doAnswer { inv -> - inv.getArgument<(EventBatchWriter) -> Unit>(0).invoke(mockEventBatchWriter) - } - - bufferA = Buffer(fakeBufferSize) - bufferB = Buffer(fakeBufferSize) - pipelineA = Pipeline(mockSdkCore, mockReaderA, bufferA, mockSerializerA, mockDataWriter, mockInternalLogger) - pipelineB = Pipeline(mockSdkCore, mockReaderB, bufferB, mockSerializerB, mockDataWriter, mockInternalLogger) - - testedTimeseries = RumSessionScopeTimeseries( - 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) - } - - @Test - fun `M schedule one runnable per pipeline W onSessionStart()`() { - // When - testedTimeseries.onSessionStart() - - // Then - verify(mockExecutor).schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) - verify(mockExecutor).schedule(any(), eq(fakeIntervalBMs), eq(TimeUnit.MILLISECONDS)) - } - - @Test - fun `M not write events W onSessionStop() { never started }`() { - // When - testedTimeseries.onSessionStop() - - // Then - verify(mockDataWriter, never()).write(any(), any(), any()) - } - - @Test - fun `M not shut down shared executor W onSessionStop()`() { - // Given - testedTimeseries.onSessionStart() - - // When - testedTimeseries.onSessionStop() - - // Then — executor is owned by the SDK core and reused across components - verify(mockExecutor, never()).shutdown() - verify(mockExecutor, never()).shutdownNow() - } - - @Test - fun `M not write events W onSessionStart()+onSessionStop() { buffers empty }`() { - // Given - testedTimeseries.onSessionStart() - - // When - testedTimeseries.onSessionStop() - - // Then - verify(mockDataWriter, never()).write(any(), any(), any()) - } - - @Test - fun `M log error and continue W onSessionStop() { serializer throws on pipelineA }`(forge: Forge) { - // Given - val fakeError = RuntimeException("serializer failure") - val fakeJson = JsonObject().apply { addProperty("k", "v") } - whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockReaderB.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doThrow fakeError - whenever(mockSerializerB.serialize(any(), any())) doReturn fakeJson - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - val runnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) - runnableA.run() - runnableB.run() - - // When - testedTimeseries.onSessionStop() - - // Then — error logged for pipelineA, pipelineB still flushed - mockInternalLogger.verifyLog( - InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - "Timeseries serialization 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) { - // Given - val fakeJson = JsonObject().apply { addProperty("k", "v") } - whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doReturn fakeJson - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - runnableA.run() - - // When - testedTimeseries.onSessionStop() - - // Then - verify(mockSerializerA).serialize(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) { - // Given - val element = forge.getForgery>() - val dataPoints = List(fakeBufferSize) { element } - val fakeJson = JsonObject().apply { addProperty("a", "1") } - whenever(mockReaderA.read()) doReturn element - whenever(mockSerializerA.serialize(any(), eq(dataPoints))) doReturn fakeJson - - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - repeat(fakeBufferSize) { runnableA.run() } - - // Then - verify(mockSerializerA).serialize(any(), any()) - verify(mockDataWriter).write(any(), eq(fakeJson), eq(EventType.DEFAULT)) - } - - @Test - fun `M reschedule sample W sample tick runs`(forge: Forge) { - // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - runnableA.run() - - // Then - 1 schedule from start() + 1 reschedule from sample tick - verify(mockExecutor, times(2)) - .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) - } - - @Test - fun `M not write events W sample tick { buffer not full }`(forge: Forge) { - // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - 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(mockDataWriter, never()).write(any(), any(), any()) - } - - @Test - fun `M not start twice W onSessionStart() { called twice }`() { - // When - testedTimeseries.onSessionStart() - testedTimeseries.onSessionStart() - - // Then — executor.schedule called exactly once per pipeline (not doubled) - verify(mockExecutor).schedule( - any(), - eq(fakeIntervalAMs), - eq(TimeUnit.MILLISECONDS) - ) - verify(mockExecutor).schedule( - any(), - eq(fakeIntervalBMs), - eq(TimeUnit.MILLISECONDS) - ) - } - - @Test - fun `M not throw W onSessionStop() { called twice }`() { - // Given - testedTimeseries.onSessionStart() - - // When + Then — must not throw - testedTimeseries.onSessionStop() - 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 - 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) - ) - } - - @Test - fun `M log error 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 - mockInternalLogger.verifyLog( - InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - RumSessionScopeTimeseries.ERROR_SAMPLING_FAILED, - fakeError - ) - } - - @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. - 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 = RumSessionScopeTimeseries( - pipelines = listOf(pipeline), - internalLogger = mockInternalLogger, - collectInBackground = false, - scheduledExecutorService = mockExecutor - ) - timeseries.onViewTypeUpdate(RumViewType.FOREGROUND) - timeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - runnableA.run() - - // Then - mockInternalLogger.verifyLog( - InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - RumSessionScopeTimeseries.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 { serializer throws }`(forge: Forge) { - // Given — serializer 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") - whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockSerializerA.serialize(any(), any())) doThrow fakeError - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - repeat(fakeBufferSize) { runnableA.run() } - - // 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. - mockInternalLogger.verifyLog( - InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - "Timeseries serialization failed", - fakeError - ) - verify(mockDataWriter, never()).write(any(), any(), any()) - verify(mockExecutor, times(fakeBufferSize + 1)) - .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) - } - - @Test - fun `M log error and reschedule W sample tick { write context resolution throws }`(forge: Forge) { - // Given — withWriteContext() itself throws (context/scope resolution failure), outside - // Pipeline's own try/catch, so it propagates up to the sampling try/catch. - val fakeError = RuntimeException("write context resolution failure") - whenever(mockReaderA.read()) doReturn forge.getForgery>() - whenever(mockRumFeatureScope.withWriteContext(any(), any())) doThrow fakeError - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - repeat(fakeBufferSize) { runnableA.run() } - - // Then - mockInternalLogger.verifyLog( - InternalLogger.Level.ERROR, - targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY), - RumSessionScopeTimeseries.ERROR_SAMPLING_FAILED, - fakeError - ) - verify(mockExecutor, times(fakeBufferSize + 1)) - .schedule(any(), eq(fakeIntervalAMs), eq(TimeUnit.MILLISECONDS)) - } - - @Test - fun `M not reschedule W stopped { sample tick skips try block }`() { - // Given - testedTimeseries.onSessionStart() - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - testedTimeseries.onSessionStop() - - // When - runnableA.run() - - // Then — no additional schedule after the one from start() - verify(mockExecutor).schedule( - any(), - eq(fakeIntervalAMs), - eq(TimeUnit.MILLISECONDS) - ) - } - - @Test - fun `M suspend chain W sample tick { background, collectInBackground = false }`(forge: Forge) { - // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() - testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - 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) - ) - } - - @Test - fun `M sample W sample tick { background, collectInBackground = true }`(forge: Forge) { - // Given - whenever(mockReaderA.read()) doReturn forge.getForgery>() - val bgTimeseries = RumSessionScopeTimeseries( - pipelines = listOf(pipelineA, pipelineB), - internalLogger = mockInternalLogger, - collectInBackground = true, - scheduledExecutorService = mockExecutor - ) - bgTimeseries.onSessionStart() - bgTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - val runnableA = captureScheduledRunnableForInterval(fakeIntervalAMs) - - // When - runnableA.run() - - // Then — sample taken even in background - verify(mockReaderA).read() - } - - @Test - fun `M resume scheduling W onViewTypeUpdate() { background → foreground }`() { - // Given - testedTimeseries.onSessionStart() - // Transition to background: suspends chains - 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() - - // When — app returns to foreground - testedTimeseries.onViewTypeUpdate(RumViewType.FOREGROUND) - - // Then — scheduling resumed (one new schedule per pipeline) - verify(mockExecutor, times(schedulesAfterSuspend + 1)) - .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>() - 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 - - // Resume creates a new generation and schedules fresh ticks for both pipelines - 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 - 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. - // - // Given - testedTimeseries.onSessionStart() - testedTimeseries.onViewTypeUpdate(RumViewType.BACKGROUND) - val oldRunnableB = captureScheduledRunnableForInterval(fakeIntervalBMs) - // Resume: state = RUNNING, gen = 2; 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() - - // 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 captureScheduledRunnableForInterval(intervalMs: Long): Runnable { - val captor = argumentCaptor() - verify(mockExecutor).schedule(captor.capture(), eq(intervalMs), eq(TimeUnit.MILLISECONDS)) - return captor.firstValue - } -} 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 new file mode 100644 index 0000000000..277ca06f10 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvCollector.kt @@ -0,0 +1,135 @@ +/* + * 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.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.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.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 [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, EventFactory>>, + private val datadogContext: DatadogContext, + private val rumContext: RumContext, + private val customAttributes: Map, + private val eventSerializer: RumEventSerializer +) : TimeseriesCollector { + + private val emitted = mutableListOf() + + /** All JSON events produced by the pipelines so far. */ + val captured: List get() = emitted.toList() + + /** + * 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, eventFactory) in pipelines) { + while (reader.hasNext()) { + buffer.add(reader.read()) + if (buffer.isFull()) flush(buffer, eventFactory) + } + flush(buffer, eventFactory) + } + } + + private fun flush(buffer: Buffer, eventFactory: EventFactory) = buffer.drain() + .takeIf { it.isNotEmpty() } + ?.let { eventFactory.create(datadogContext, rumContext, it, customAttributes) } + ?.let(eventSerializer::serialize) + ?.let(JsonParser::parseString) + ?.let { emitted.add(it.asJsonObject) } + + override fun onSessionStop() = Unit + + override fun onRumContextUpdate(newRumContext: RumContext) = Unit + + companion object { + + /** + * Builds a [CsvCollector] with the same shape as `DefaultTimeseriesFactory`: + * a memory pipeline followed by a CPU pipeline, each backed by [CSVReader] and the + * production [MemoryEventFactory] / [CpuEventFactory]. + */ + fun create( + csvContent: String, + sessionType: RumSessionType, + totalRamBytes: Long, + bufferSize: Int, + 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/CsvTimeseries.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvTimeseries.kt deleted file mode 100644 index 7444584bd0..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/CsvTimeseries.kt +++ /dev/null @@ -1,105 +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.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.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.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`, - * 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( - private val pipelines: List, JsonSerializer>>, - private val datadogContext: DatadogContext -) : Timeseries { - - private val emitted = mutableListOf() - - /** All JSON events produced by the pipelines so far. */ - val captured: List get() = emitted.toList() - - /** - * Walks each (reader, buffer, serializer) 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) { - while (reader.hasNext()) { - buffer.add(reader.read()) - if (buffer.isFull()) flush(buffer, serializer) - } - flush(buffer, serializer) - } - } - - private fun flush(buffer: Buffer, serializer: JsonSerializer) = buffer.drain() - .takeIf { it.isNotEmpty() } - ?.let { serializer.serialize(datadogContext, it) } - ?.let(emitted::add) - - override fun onSessionStop() = Unit - - override fun onViewTypeUpdate(newViewType: RumViewType) = Unit - - companion object { - - /** - * Builds a [CsvTimeseries] with the same shape as `RumSessionScopeTimeseriesFactory`: - * a memory pipeline followed by a CPU pipeline, each backed by [CSVReader] and the - * production [MemoryEventSerializer] / [CpuEventSerializer]. - */ - @Suppress("LongParameterList") - fun create( - csvContent: String, - sessionId: String, - applicationId: String, - sessionType: RumSessionType, - totalRamBytes: Long, - bufferSize: Int, - timeProvider: TimeProvider, - datadogContext: DatadogContext - ) = CsvTimeseries( - 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 - ) - ) - ) - ) - - const val METRIC_MEMORY_USAGE: String = "memory_usage" - const val METRIC_CPU_USAGE: String = "cpu_usage" - } -} 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 new file mode 100644 index 0000000000..28f37cfdd2 --- /dev/null +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesCollectorEndToEndTest.kt @@ -0,0 +1,157 @@ +/* + * 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.csv + +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.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 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.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.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 + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +@ForgeConfiguration(Configurator::class) +internal class TimeseriesCollectorEndToEndTest { + + @Mock + lateinit var mockTimeProvider: TimeProvider + + private lateinit var capturedMemoryEvents: List + private lateinit var capturedCpuEvents: List + + @BeforeEach + fun `set up`(forge: Forge) { + whenever(mockTimeProvider.getServerTimestampMillis()) doReturn FIXED_DATE_MS + + val testedTimeseries = CsvCollector.create( + csvContent = loadResource("fixtures/timeseries/input_memory_cpu.csv"), + sessionType = RumSessionType.USER, + totalRamBytes = TOTAL_RAM_BYTES, + bufferSize = BATCH_SIZE, + timeProvider = mockTimeProvider, + forge = forge, + internalLogger = mock() + ) + testedTimeseries.onSessionStart() + 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 + assertThat(capturedMemoryEvents.size).isEqualTo(2) + assertThat(capturedCpuEvents.size).isEqualTo(2) + } + + @Test + 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 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 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 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`() { + 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`() { + capturedMemoryEvents.forEach { actual -> + TimeseriesMemoryEventAssert.assertThat(actual) + .hasTimeseriesStartNotAfterEnd() + } + capturedCpuEvents.forEach { actual -> + TimeseriesCpuEventAssert.assertThat(actual) + .hasTimeseriesStartNotAfterEnd() + } + } + + 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 fun loadExpectedMemoryTimeseries(path: String): TimeseriesMemoryEvent = + TimeseriesMemoryEvent.fromJson(loadResource(path)) + + private fun loadExpectedCpuTimeseries(path: String): TimeseriesCpuEvent = + TimeseriesCpuEvent.fromJson(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() } + } + } +} 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/TimeseriesEndToEndTest.kt deleted file mode 100644 index 444b41f7ca..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/csv/TimeseriesEndToEndTest.kt +++ /dev/null @@ -1,252 +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.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.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.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 -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.math.BigDecimal -import java.util.UUID - -@Extensions( - ExtendWith(MockitoExtension::class), - ExtendWith(ForgeExtension::class) -) -@MockitoSettings(strictness = Strictness.LENIENT) -@ForgeConfiguration(Configurator::class) -internal class TimeseriesEndToEndTest { - - @Mock - lateinit var mockTimeProvider: TimeProvider - - @Mock - lateinit var mockDatadogContext: DatadogContext - - private lateinit var csvContent: String - private lateinit var emitted: List - - @BeforeEach - fun `set up`() { - whenever(mockTimeProvider.getDeviceTimestampMillis()) doReturn FIXED_DATE_MS - - csvContent = loadResource("fixtures/timeseries/input_memory_cpu.csv") - val testedTimeseries = CsvTimeseries.create( - csvContent = csvContent, - sessionId = SESSION_ID, - applicationId = APPLICATION_ID, - sessionType = RumSessionType.USER, - totalRamBytes = TOTAL_RAM_BYTES, - bufferSize = BATCH_SIZE, - timeProvider = mockTimeProvider, - datadogContext = mockDatadogContext - ) - testedTimeseries.onSessionStart() - testedTimeseries.onSessionStop() - emitted = testedTimeseries.captured - } - - @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) - } - - @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)) - } - - @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)) - } - - @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)) - } - - @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)) - } - - @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 - } - } - - @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) - } - } - - // 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 - } - } - - 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 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 const val KEY_ID: String = "id" - } -} 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/VitalReaderDataPointsReaderTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/timeseries/provider/VitalReaderWrapperTest.kt similarity index 72% 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..d863626dfa 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,24 +33,24 @@ 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 + @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 @@ -68,7 +67,7 @@ internal class VitalReaderDataPointsReaderTest { } @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 @@ -81,14 +80,4 @@ internal class VitalReaderDataPointsReaderTest { // 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 3365add0a7..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/timeseries/TimeseriesConfigurationTest.kt +++ /dev/null @@ -1,84 +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) - } - - @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() - } -} 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)) + } + } +} 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"/> +