Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion dd-sdk-android-core/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ fun <R: Any?> com.datadog.android.api.InternalLogger.measureMethodCallPerf(Class
fun FeatureScope.getContextFuture(Set<String> = emptySet()): java.util.concurrent.Future<com.datadog.android.api.context.DatadogContext?>?
interface com.datadog.android.api.feature.FeatureSdkCore : com.datadog.android.api.SdkCore
val internalLogger: com.datadog.android.api.InternalLogger
val timeProvider: com.datadog.android.internal.time.TimeProvider
fun registerFeature(Feature)
fun getFeature(String): FeatureScope?
fun updateFeatureContext(String, Boolean = true, (MutableMap<String, Any?>) -> Unit)
Expand Down Expand Up @@ -403,7 +404,7 @@ interface com.datadog.android.core.sampling.Sampler<T: Any>
interface com.datadog.android.core.thread.FlushableExecutorService : java.util.concurrent.ExecutorService
fun drainTo(MutableCollection<Runnable>)
interface Factory
fun create(com.datadog.android.api.InternalLogger, String, com.datadog.android.core.configuration.BackPressureStrategy): FlushableExecutorService
fun create(com.datadog.android.api.InternalLogger, String, com.datadog.android.core.configuration.BackPressureStrategy, com.datadog.android.internal.time.TimeProvider): FlushableExecutorService
interface com.datadog.android.event.EventMapper<T: Any>
fun map(T): T?
class com.datadog.android.event.MapperSerializer<T: Any> : com.datadog.android.core.persistence.Serializer<T>
Expand Down
3 changes: 2 additions & 1 deletion dd-sdk-android-core/api/dd-sdk-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ public abstract interface class com/datadog/android/api/feature/FeatureSdkCore :
public abstract fun getFeature (Ljava/lang/String;)Lcom/datadog/android/api/feature/FeatureScope;
public abstract fun getFeatureContext (Ljava/lang/String;Z)Ljava/util/Map;
public abstract fun getInternalLogger ()Lcom/datadog/android/api/InternalLogger;
public abstract fun getTimeProvider ()Lcom/datadog/android/internal/time/TimeProvider;
public abstract fun registerFeature (Lcom/datadog/android/api/feature/Feature;)V
public abstract fun removeContextUpdateReceiver (Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
public abstract fun removeEventReceiver (Ljava/lang/String;)V
Expand Down Expand Up @@ -1016,7 +1017,7 @@ public abstract interface class com/datadog/android/core/thread/FlushableExecuto
}

public abstract interface class com/datadog/android/core/thread/FlushableExecutorService$Factory {
public abstract fun create (Lcom/datadog/android/api/InternalLogger;Ljava/lang/String;Lcom/datadog/android/core/configuration/BackPressureStrategy;)Lcom/datadog/android/core/thread/FlushableExecutorService;
public abstract fun create (Lcom/datadog/android/api/InternalLogger;Ljava/lang/String;Lcom/datadog/android/core/configuration/BackPressureStrategy;Lcom/datadog/android/internal/time/TimeProvider;)Lcom/datadog/android/core/thread/FlushableExecutorService;
}

public abstract interface class com/datadog/android/event/EventMapper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.datadog.android.api.feature

import com.datadog.android.api.InternalLogger
import com.datadog.android.api.SdkCore
import com.datadog.android.internal.time.TimeProvider
import okhttp3.Call
import okhttp3.OkHttpClient
import java.util.UUID
Expand All @@ -27,6 +28,11 @@ interface FeatureSdkCore : SdkCore {
*/
val internalLogger: InternalLogger

/**
* The [TimeProvider] used by this core instance for current timestamps.
*/
val timeProvider: TimeProvider

/**
* Registers a feature to this instance of the Datadog SDK.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ internal class CoreFeature(
.writeTimeout(NETWORK_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.protocols(listOf(Protocol.HTTP_2, Protocol.HTTP_1_1))
.connectionSpecs(listOf(connectionSpec))
.dns(RotatingDnsResolver()) // NPE cannot happen here
.dns(RotatingDnsResolver(timeProvider = timeProvider)) // NPE cannot happen here
.build()
}

Expand Down Expand Up @@ -327,7 +327,7 @@ internal class CoreFeature(
}

fun createExecutorService(executorContext: String): ExecutorService {
return executorServiceFactory.create(internalLogger, executorContext, backpressureStrategy)
return executorServiceFactory.create(internalLogger, executorContext, backpressureStrategy, timeProvider)
}

fun createScheduledExecutorService(executorContext: String): ScheduledExecutorService {
Expand Down Expand Up @@ -652,7 +652,8 @@ internal class CoreFeature(
persistenceExecutorService = executorServiceFactory.create(
internalLogger = internalLogger,
executorContext = "storage",
backPressureStrategy = backpressureStrategy
backPressureStrategy = backpressureStrategy,
timeProvider = timeProvider
)
val contextQueue = BackPressuredBlockingQueue<Runnable>(
internalLogger,
Expand All @@ -662,7 +663,8 @@ internal class CoreFeature(
// just notify when reached
onItemDropped = {},
onThresholdReached = {},
backpressureMitigation = null
backpressureMitigation = null,
timeProvider = timeProvider
)
@Suppress("UnsafeThirdPartyFunctionCall") // all parameters are safe
contextExecutorService = ThreadPoolExecutor(
Expand Down Expand Up @@ -753,8 +755,8 @@ internal class CoreFeature(
" process of your application."

internal val DEFAULT_FLUSHABLE_EXECUTOR_SERVICE_FACTORY =
FlushableExecutorService.Factory { logger, executorContext, backPressureStrategy ->
BackPressureExecutorService(logger, executorContext, backPressureStrategy)
FlushableExecutorService.Factory { logger, executorContext, backPressureStrategy, timeProvider ->
BackPressureExecutorService(logger, executorContext, backPressureStrategy, timeProvider)
}

internal val DEFAULT_SCHEDULED_EXECUTOR_SERVICE_FACTORY =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.datadog.android.core.internal.utils.submitSafe
import com.datadog.android.core.thread.FlushableExecutorService
import com.datadog.android.error.internal.CrashReportsFeature
import com.datadog.android.internal.telemetry.InternalTelemetryEvent
import com.datadog.android.internal.time.TimeProvider
import com.datadog.android.privacy.TrackingConsent
import com.google.gson.JsonObject
import okhttp3.Call
Expand Down Expand Up @@ -101,7 +102,7 @@ internal class DatadogCore(
/** @inheritDoc */
override val time: TimeInfo
get() {
return coreFeature.timeProvider.composeTimeInfo()
return timeProvider.composeTimeInfo()
}

/** @inheritDoc */
Expand All @@ -115,6 +116,10 @@ internal class DatadogCore(
/** @inheritDoc */
override val internalLogger: InternalLogger = internalLoggerProvider(this)

/** @inheritDoc */
override val timeProvider: TimeProvider
get() = coreFeature.timeProvider

/** @inheritDoc */
override var isDeveloperModeEnabled: Boolean = false
internal set
Expand Down Expand Up @@ -452,7 +457,7 @@ internal class DatadogCore(
executorServiceFactory ?: CoreFeature.DEFAULT_FLUSHABLE_EXECUTOR_SERVICE_FACTORY
coreFeature = CoreFeature(
internalLogger,
DefaultAppStartTimeProvider(),
DefaultAppStartTimeProvider(timeProviderFactory = { timeProvider }),
flushableExecutorServiceFactory,
CoreFeature.DEFAULT_SCHEDULED_EXECUTOR_SERVICE_FACTORY
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import com.datadog.android.core.InternalSdkCore
import com.datadog.android.core.internal.logger.SdkInternalLogger
import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeResolver
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
import com.datadog.android.internal.time.DefaultTimeProvider
import com.datadog.android.internal.time.TimeProvider
import com.datadog.android.privacy.TrackingConsent
import com.google.gson.JsonObject
import okhttp3.Call
Expand All @@ -41,15 +43,16 @@ import java.util.concurrent.TimeUnit
/**
* A no-op implementation of [SdkCore].
*/
@Suppress("TooManyFunctions")
internal object NoOpInternalSdkCore : InternalSdkCore {

override val name: String = "no-op"

override val time: TimeInfo = with(System.currentTimeMillis()) {
override val time: TimeInfo = with(timeProvider.getDeviceTimestampMillis()) {
TimeInfo.EMPTY.copy(
deviceTimeNs = TimeUnit.MILLISECONDS.toNanos(this),
serverTimeNs = TimeUnit.MILLISECONDS.toNanos(this)
serverTimeNs = TimeUnit.MILLISECONDS.toNanos(this),
serverTimeOffsetNs = 0L,
serverTimeOffsetMs = 0L
)
}

Expand All @@ -59,6 +62,9 @@ internal object NoOpInternalSdkCore : InternalSdkCore {
override val internalLogger: InternalLogger
get() = SdkInternalLogger(this)

override val timeProvider: TimeProvider
get() = DefaultTimeProvider()

// region InternalSdkCore

override val networkInfo: NetworkInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ internal class SdkFeature(
executorService = coreFeature.persistenceExecutorService,
filePersistenceConfig = filePersistenceConfig,
internalLogger = internalLogger,
metricsDispatcher = metricsDispatcher
metricsDispatcher = metricsDispatcher,
timeProvider = coreFeature.timeProvider
)
this.fileOrchestrator = fileOrchestrator

Expand Down Expand Up @@ -398,7 +399,8 @@ internal class SdkFeature(
sdkVersion = coreFeature.sdkVersion,
androidInfoProvider = coreFeature.androidInfoProvider,
executionTimer = GlobalBenchmark.createExecutionTimer(
track = wrappedFeature.name
track = wrappedFeature.name,
timeProvider = coreFeature.timeProvider
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.datadog.android.core.internal.data.upload

import com.datadog.android.internal.time.TimeProvider
import okhttp3.Dns
import java.net.InetAddress
import kotlin.time.Duration
Expand All @@ -14,17 +15,17 @@ import kotlin.time.Duration.Companion.nanoseconds

internal class RotatingDnsResolver(
private val delegate: Dns = Dns.SYSTEM,
private val ttl: Duration = TTL_30_MIN
private val ttl: Duration = TTL_30_MIN,
private val timeProvider: TimeProvider
) : Dns {

data class ResolvedHost(
val hostname: String,
val addresses: MutableList<InetAddress>
val addresses: MutableList<InetAddress>,
private val resolutionTimestamp: Long
) {
private val resolutionTimestamp: Long = System.nanoTime()

fun getAge(): Duration {
return (System.nanoTime() - resolutionTimestamp).nanoseconds
fun getAge(currentTime: Long): Duration {
return (currentTime - resolutionTimestamp).nanoseconds
}

fun rotate() {
Expand All @@ -50,7 +51,11 @@ internal class RotatingDnsResolver(
} else {
@Suppress("UnsafeThirdPartyFunctionCall") // handled by caller
val result = delegate.lookup(hostname)
knownHosts[hostname] = ResolvedHost(hostname, result.toMutableList())
knownHosts[hostname] = ResolvedHost(
hostname,
result.toMutableList(),
timeProvider.getDeviceElapsedTimeNanos()
)
safeCopy(result)
}
}
Expand All @@ -66,7 +71,7 @@ internal class RotatingDnsResolver(
}

private fun isValid(knownHost: ResolvedHost): Boolean {
return knownHost.getAge() < ttl && knownHost.addresses.isNotEmpty()
return knownHost.getAge(timeProvider.getDeviceElapsedTimeNanos()) < ttl && knownHost.addresses.isNotEmpty()
}

// endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.datadog.android.core.sampling.RateBasedSampler
import com.datadog.android.internal.attributes.LocalAttribute
import com.datadog.android.internal.attributes.enrichWithNonNullAttribute
import com.datadog.android.internal.telemetry.InternalTelemetryEvent
import com.datadog.android.internal.time.DefaultTimeProvider

internal class SdkInternalLogger(
private val sdkCore: FeatureSdkCore?,
Expand Down Expand Up @@ -140,7 +141,8 @@ internal class SdkInternalLogger(
internalLogger = this,
operationName = operationName,
callerClass = callerClass,
creationSampleRate = samplingRate
creationSampleRate = samplingRate,
timeProvider = sdkCore?.timeProvider ?: DefaultTimeProvider()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal class BatchMetricsDispatcher(
private val uploadConfiguration: DataUploadConfiguration?,
private val filePersistenceConfig: FilePersistenceConfig,
private val internalLogger: InternalLogger,
private val dateTimeProvider: TimeProvider
private val timeProvider: TimeProvider

) : MetricsDispatcher, ProcessLifecycleMonitor.Callback {

Expand Down Expand Up @@ -90,7 +90,7 @@ internal class BatchMetricsDispatcher(
numPendingBatches: Int
): Map<String, Any?>? {
val fileCreationTimestamp = file.nameAsTimestampSafe(internalLogger) ?: return null
val fileAgeInMillis = dateTimeProvider.getDeviceTimestamp() - fileCreationTimestamp
val fileAgeInMillis = timeProvider.getDeviceTimestampMillis() - fileCreationTimestamp
if (fileAgeInMillis < 0) {
// the device time was manually modified or the time zone changed
// we are dropping this metric to not skew our charts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,28 @@ import com.datadog.android.api.InternalLogger
import com.datadog.android.core.metrics.MethodCallSamplingRate
import com.datadog.android.core.metrics.PerformanceMetric
import com.datadog.android.core.metrics.PerformanceMetric.Companion.METRIC_TYPE
import com.datadog.android.internal.time.TimeProvider

/**
* Performance metric to measure the execution time for a method.
* @param internalLogger - an instance of the internal logger.
* @param operationName the operation name
* @param callerClass - the class calling the performance metric.
* @param creationSampleRate - sampling frequency used to create the metric
* @param startTime - the time when the metric is instantiated, to be used as the start point for the measurement.
* @param timeProvider - the provider for time measurements.
*/
internal class MethodCalledTelemetry(
internal val internalLogger: InternalLogger,
internal val operationName: String,
internal val callerClass: String,
internal val creationSampleRate: Float,
internal val startTime: Long = System.nanoTime()
internal val timeProvider: TimeProvider
) : PerformanceMetric {

internal val startTime: Long = timeProvider.getDeviceElapsedTimeNanos()

override fun stopAndSend(isSuccessful: Boolean) {
val executionTime = System.nanoTime() - startTime
val executionTime = timeProvider.getDeviceElapsedTimeNanos() - startTime
val additionalProperties: MutableMap<String, Any> = mutableMapOf()

additionalProperties[EXECUTION_TIME] = executionTime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import androidx.annotation.WorkerThread
import com.datadog.android.api.InternalLogger
import com.datadog.android.core.internal.persistence.file.FileMover
import com.datadog.android.core.internal.persistence.file.FileOrchestrator
import com.datadog.android.internal.time.TimeProvider
import com.datadog.android.privacy.TrackingConsent

internal class ConsentAwareFileMigrator(
private val fileMover: FileMover,
private val internalLogger: InternalLogger
private val internalLogger: InternalLogger,
private val timeProvider: TimeProvider
) : DataMigrator<TrackingConsent> {

@WorkerThread
Expand Down Expand Up @@ -47,7 +49,8 @@ internal class ConsentAwareFileMigrator(
WipeDataMigrationOperation(
previousFileOrchestrator.getRootDir(),
fileMover,
internalLogger
internalLogger,
timeProvider
)
}

Expand All @@ -56,7 +59,8 @@ internal class ConsentAwareFileMigrator(
WipeDataMigrationOperation(
newFileOrchestrator.getRootDir(),
fileMover,
internalLogger
internalLogger,
timeProvider
)
}

Expand All @@ -65,7 +69,8 @@ internal class ConsentAwareFileMigrator(
previousFileOrchestrator.getRootDir(),
newFileOrchestrator.getRootDir(),
fileMover,
internalLogger
internalLogger,
timeProvider
)
}

Expand Down
Loading
Loading