Skip to content

Commit 724b5ef

Browse files
committed
Merge branch 'develop' into leo.romanovsky/android-flags-exposure-cache-cycle
2 parents 982f786 + c6e8fe9 commit 724b5ef

171 files changed

Lines changed: 8461 additions & 1219 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ variables:
1010
DD_COMMON_AGENT_CONFIG: "dd.env=ci,dd.trace.enabled=false,dd.jmx.fetch.enabled=false"
1111

1212
KUBERNETES_MEMORY_REQUEST: "8Gi"
13-
KUBERNETES_MEMORY_LIMIT: "13Gi"
13+
KUBERNETES_MEMORY_LIMIT: "32Gi"
1414

1515
EMULATOR_NAME: "android_emulator"
1616
ANDROID_ARCH: "arm64-v8a"

CHANGELOG.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,49 @@
1+
# 3.11.0 / 2026-06-16
2+
3+
* [FEATURE] Support `addEvent` for OpenTelemetry spans (logging events). See [#3377](https://github.com/DataDog/dd-sdk-android/pull/3377)
4+
* [FEATURE] Add cross-product sampling rebasing for RUM-to-APM correlation. See [#3402](https://github.com/DataDog/dd-sdk-android/pull/3402)
5+
* [FEATURE] Report carrier info on Android API 24+. See [#3449](https://github.com/DataDog/dd-sdk-android/pull/3449)
6+
* [FEATURE] Add trace sampling decision to `DatadogEventBridge`. See [#3495](https://github.com/DataDog/dd-sdk-android/pull/3495)
7+
* [IMPROVEMENT] Preserve custom `DeterministicTraceSampler` subclasses from rebasing. See [#3455](https://github.com/DataDog/dd-sdk-android/pull/3455)
8+
* [IMPROVEMENT] Rename `last_failure_status` to `retry_after`. See [#3459](https://github.com/DataDog/dd-sdk-android/pull/3459)
9+
* [IMPROVEMENT] Optimize `isMainProcess` detection. See [#3489](https://github.com/DataDog/dd-sdk-android/pull/3489)
10+
* [IMPROVEMENT] Add name support for work units in `BackPressureExecutorService#submit`. See [#3492](https://github.com/DataDog/dd-sdk-android/pull/3492)
11+
* [IMPROVEMENT] Remove regex usage in `MemoryVitalReader`. See [#3499](https://github.com/DataDog/dd-sdk-android/pull/3499)
12+
* [IMPROVEMENT] Read process importance early. See [#3504](https://github.com/DataDog/dd-sdk-android/pull/3504)
13+
* [IMPROVEMENT] Enforce schema character set on `vital.name` in Operation APIs. See [#3393](https://github.com/DataDog/dd-sdk-android/pull/3393)
14+
* [IMPROVEMENT] Route `androidNetworkInstrumentation` through `InternalLogger#logApiUsage`. See [#3516](https://github.com/DataDog/dd-sdk-android/pull/3516)
15+
* [IMPROVEMENT] Flags: rename flag names to flag keys. See [#3527](https://github.com/DataDog/dd-sdk-android/pull/3527)
16+
* [IMPROVEMENT] Write `CUSTOM` RUM actions immediately. See [#3525](https://github.com/DataDog/dd-sdk-android/pull/3525)
17+
* [IMPROVEMENT] Move broadcast-receiver dispatch off the main thread to reduce ANRs. See [#3524](https://github.com/DataDog/dd-sdk-android/pull/3524)
18+
* [IMPROVEMENT] Flags: thread `allocationKey` into `ResolutionDetails` flag metadata. See [#3534](https://github.com/DataDog/dd-sdk-android/pull/3534)
19+
* [IMPROVEMENT] Pass `InternalLogger` through the Session Replay mappers. See [#3518](https://github.com/DataDog/dd-sdk-android/pull/3518)
20+
* [IMPROVEMENT] Add `Context.getSystemServiceAs` extension. See [#3451](https://github.com/DataDog/dd-sdk-android/pull/3451)
21+
* [BUGFIX] Catch exception on the battery level query. See [#3453](https://github.com/DataDog/dd-sdk-android/pull/3453)
22+
* [BUGFIX] Catch `Throwable.loggableStackTrace()` throws. See [#3458](https://github.com/DataDog/dd-sdk-android/pull/3458)
23+
* [BUGFIX] Ignore dropped local active span in RUM-to-APM path. See [#3406](https://github.com/DataDog/dd-sdk-android/pull/3406)
24+
* [BUGFIX] Atomically write NDK crash logs and catch `NumberFormatException`. See [#3425](https://github.com/DataDog/dd-sdk-android/pull/3425)
25+
* [BUGFIX] Fix tap target mis-attribution for views clipped by scrolling ancestors. See [#3473](https://github.com/DataDog/dd-sdk-android/pull/3473)
26+
* [BUGFIX] Make file write atomic. See [#3476](https://github.com/DataDog/dd-sdk-android/pull/3476)
27+
* [BUGFIX] Catch `IllegalArgumentException` when reading trace input stream for last fatal ANR. See [#3483](https://github.com/DataDog/dd-sdk-android/pull/3483)
28+
* [BUGFIX] Fix `WorkDatabase` initialization crash in R8 full mode. See [#3502](https://github.com/DataDog/dd-sdk-android/pull/3502)
29+
* [BUGFIX] Catch errors in `convertToRumViewAttributes`. See [#3497](https://github.com/DataDog/dd-sdk-android/pull/3497)
30+
* [BUGFIX] Fix gradients not showing in Compose Session Replay. See [#3471](https://github.com/DataDog/dd-sdk-android/pull/3471)
31+
* [BUGFIX] Fix hidden API reflection noise in Session Replay drawable mappers. See [#3539](https://github.com/DataDog/dd-sdk-android/pull/3539)
32+
* [BUGFIX] Fix wrong API doc for text and input privacy configuration in Session Replay. See [#3520](https://github.com/DataDog/dd-sdk-android/pull/3520)
33+
* [MAINTENANCE] `NoOpImplementation` improvements: support for nested interfaces. See [#3468](https://github.com/DataDog/dd-sdk-android/pull/3468)
34+
* [MAINTENANCE] `NoOpImplementation` improvements: guard NoOp generation against restricted-visibility. See [#3469](https://github.com/DataDog/dd-sdk-android/pull/3469)
35+
* [MAINTENANCE] `NoOpImplementation` improvements: add name collision detection and `customName` support. See [#3470](https://github.com/DataDog/dd-sdk-android/pull/3470)
36+
* [MAINTENANCE] Sign automatically created commits. See [#3462](https://github.com/DataDog/dd-sdk-android/pull/3462)
37+
* [MAINTENANCE] Bump `ktlint` and `detekt` versions. See [#3444](https://github.com/DataDog/dd-sdk-android/pull/3444)
38+
* [MAINTENANCE] Resolve dependencies through Magic Mirror Depot in CI. See [#3452](https://github.com/DataDog/dd-sdk-android/pull/3452)
39+
* [MAINTENANCE] Benchmarking: enable RUM for Session Replay baseline run. See [#3467](https://github.com/DataDog/dd-sdk-android/pull/3467)
40+
* [MAINTENANCE] Add integration test for cross-product trace sampling rebasing. See [#3464](https://github.com/DataDog/dd-sdk-android/pull/3464)
41+
* [MAINTENANCE] Benchmark: fix app crash when running baseline for the Session Replay scenario. See [#3474](https://github.com/DataDog/dd-sdk-android/pull/3474)
42+
* [MAINTENANCE] Fix flaky `InternalApiUsageDetectorTest` due to Kotlin reserved keywords in package regex. See [#3522](https://github.com/DataDog/dd-sdk-android/pull/3522)
43+
* [MAINTENANCE] Fix Detekt stack overflow on wildcard projections. See [#3528](https://github.com/DataDog/dd-sdk-android/pull/3528)
44+
* [MAINTENANCE] Bump Datadog Gradle Plugin to `1.27.0`. See [#3533](https://github.com/DataDog/dd-sdk-android/pull/3533)
45+
* [MAINTENANCE] Move `FakeSameThreadExecutorService` into core test fixtures. See [#3536](https://github.com/DataDog/dd-sdk-android/pull/3536)
46+
147
# 3.10.0 / 2026-05-13
248

349
* [FEATURE] Network headers common instrumentation. See [#3338](https://github.com/DataDog/dd-sdk-android/pull/3338)

buildSrc/src/main/kotlin/com/datadog/gradle/KotlinDSLUtils.kt

Lines changed: 0 additions & 51 deletions
This file was deleted.

buildSrc/src/main/kotlin/com/datadog/gradle/config/AndroidConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object AndroidConfig {
1919
const val MIN_SDK_FOR_AUTO = 29
2020
const val BUILD_TOOLS_VERSION = "36.0.0"
2121

22-
val VERSION = Version(3, 11, 0, Version.Type.Snapshot)
22+
val VERSION = Version(3, 12, 0, Version.Type.Snapshot)
2323
}
2424

2525
// TODO RUM-628 Switch to Java 17 bytecode

buildSrc/src/main/kotlin/com/datadog/gradle/config/DetektCustomConfig.kt

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,16 @@ fun Project.detektCustomConfig() {
113113

114114
tasks.register<JavaExec>("customDetektRules") {
115115
group = "datadog"
116+
maxHeapSize = "2g"
117+
dependsOn("printDetektClasspath")
116118

117119
classpath = files("${rootDir.absolutePath}/detekt-cli-1.23.8-all.jar")
118120

119121
args(
120122
"--config",
121123
"${rootDir.absolutePath}/detekt_custom_general.yml," +
122-
"${rootDir.absolutePath}/detekt_custom_safe_calls.yml," +
124+
"${rootDir.absolutePath}/detekt_custom_safe_calls_android.yml," +
125+
"${rootDir.absolutePath}/detekt_custom_safe_calls_third_party.yml," +
123126
"${rootDir.absolutePath}/detekt_custom_unsafe_calls.yml"
124127
)
125128
args("--plugins", "${rootDir.absolutePath}/tools/detekt/build/libs/detekt.jar")
@@ -129,18 +132,18 @@ fun Project.detektCustomConfig() {
129132

130133
val moduleDependencies = collectTransitiveProjectDependencies(project)
131134

132-
val externalDependencies = File("${projectDir.absolutePath}/detekt_classpath").readText()
133-
val moduleDependenciesClasses = moduleDependencies.joinToString(":") {
134-
"${rootDir.absolutePath}${it.replace(':', '/')}/build/extracted/classes.jar"
135-
}
136-
137-
val dependencies = if (moduleDependenciesClasses.isBlank()) {
138-
externalDependencies
139-
} else {
140-
"$externalDependencies:$moduleDependenciesClasses"
135+
doFirst {
136+
val externalDependencies = File("${projectDir.absolutePath}/detekt_classpath").readText()
137+
val moduleDependenciesClasses = moduleDependencies.joinToString(":") {
138+
"${rootDir.absolutePath}${it.replace(':', '/')}/build/extracted/classes.jar"
139+
}
140+
val dependencies = if (moduleDependenciesClasses.isBlank()) {
141+
externalDependencies
142+
} else {
143+
"$externalDependencies:$moduleDependenciesClasses"
144+
}
145+
args("-cp", dependencies)
141146
}
142-
143-
args("-cp", dependencies)
144147
}
145148
}
146149

ci/pipelines/default-pipeline.yml

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,12 @@ analysis:detekt-custom:
143143
stage: analysis
144144
timeout: 1h
145145
script:
146-
- ./gradlew assembleLibrariesRelease --stacktrace
146+
- ./gradlew assembleLibrariesRelease --parallel --stacktrace
147147
- ./gradlew unzipAarForDetekt --stacktrace
148148
- ./gradlew :tools:detekt:jar --stacktrace
149149
- ./gradlew printDetektClasspath --stacktrace
150150
- curl -sSLO https://github.com/detekt/detekt/releases/download/v1.23.8/detekt-cli-1.23.8-all.jar
151-
- ./gradlew customDetektRules
152-
151+
- ./gradlew customDetektRules --parallel --max-workers=4
153152

154153
# TODO RUM-1622 cleanup this section
155154
# TESTS
@@ -164,11 +163,15 @@ test:debug:
164163
script:
165164
- rm -rf ~/.gradle/daemon/
166165
- export DD_AGENT_HOST="$BUILDENV_HOST_IP"
167-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :dd-sdk-android-core:testDebugUnitTest --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
168-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :dd-sdk-android-internal:testDebugUnitTest --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
169-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :unitTestDebugFeatures --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
170-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :unitTestDebugIntegrations --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
171-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew :unitTestDebugSamples --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
166+
- >-
167+
GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:debug" ./gradlew
168+
:dd-sdk-android-core:testDebugUnitTest
169+
:dd-sdk-android-internal:testDebugUnitTest
170+
:unitTestDebugFeatures
171+
:unitTestDebugIntegrations
172+
:unitTestDebugSamples
173+
--parallel --max-workers=4 --no-daemon --build-cache --gradle-user-home cache/
174+
-Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
172175
artifacts:
173176
when: always
174177
expire_in: 1 week
@@ -205,10 +208,14 @@ test:kover:
205208
- export DD_API_KEY=$(get_secret $DD_ANDROID_SECRET__API_KEY)
206209
- export DD_APP_KEY=$(get_secret $DD_ANDROID_SECRET__APP_KEY)
207210
- CODECOV_TOKEN=$(get_secret $DD_ANDROID_SECRET__CODECOV_TOKEN)
208-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :dd-sdk-android-core:koverXmlReportRelease --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
209-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :dd-sdk-android-internal:koverXmlReportRelease --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
210-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :koverReportFeatures --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
211-
- GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew :koverReportIntegrations --no-daemon --build-cache --gradle-user-home cache/ -Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
211+
- >-
212+
GRADLE_OPTS="-Xmx3072m" DD_TAGS="test.configuration.variant:release" ./gradlew
213+
:dd-sdk-android-core:koverXmlReportRelease
214+
:dd-sdk-android-internal:koverXmlReportRelease
215+
:koverReportFeatures
216+
:koverReportIntegrations
217+
--parallel --max-workers=4 --no-daemon --build-cache --gradle-user-home cache/
218+
-Dorg.gradle.jvmargs=-javaagent:$DD_TRACER_FOLDER/dd-java-agent.jar=$DD_COMMON_AGENT_CONFIG
212219
- bash <(cat ./ci/scripts/codecov.sh) -t $CODECOV_TOKEN
213220
- npm install -g @datadog/datadog-ci
214221
- datadog-ci coverage upload --format=jacoco . || true

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/CoreFeature.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import android.content.Context
1212
import android.content.pm.PackageInfo
1313
import android.content.pm.PackageManager
1414
import android.os.Build
15+
import android.os.Handler
1516
import android.os.Process
1617
import androidx.annotation.RequiresApi
1718
import androidx.annotation.WorkerThread
@@ -59,6 +60,7 @@ import com.datadog.android.core.internal.system.NoOpSystemInfoProvider
5960
import com.datadog.android.core.internal.system.SystemInfoProvider
6061
import com.datadog.android.core.internal.thread.BackPressureExecutorService
6162
import com.datadog.android.core.internal.thread.BackPressuredBlockingQueue
63+
import com.datadog.android.core.internal.thread.BroadcastReceiverThread
6264
import com.datadog.android.core.internal.thread.DatadogThreadFactory
6365
import com.datadog.android.core.internal.thread.LoggingScheduledThreadPoolExecutor
6466
import com.datadog.android.core.internal.thread.ScheduledExecutorServiceFactory
@@ -201,6 +203,7 @@ internal class CoreFeature(
201203
internal lateinit var uploadExecutorService: ScheduledThreadPoolExecutor
202204
internal lateinit var persistenceExecutorService: FlushableExecutorService
203205
internal lateinit var contextExecutorService: ThreadPoolExecutor
206+
internal lateinit var broadcastReceiverThread: BroadcastReceiverThread
204207
internal lateinit var backpressureStrategy: BackPressureStrategy
205208

206209
internal var localDataEncryption: Encryption? = null
@@ -589,15 +592,17 @@ internal class CoreFeature(
589592
// Tracking Consent Provider
590593
trackingConsentProvider = TrackingConsentProvider(consent)
591594

595+
val broadcastReceiverHandler = Handler(broadcastReceiverThread.looper)
596+
592597
// System Info Provider
593598
systemInfoProvider = BroadcastReceiverSystemInfoProvider(
594599
internalLogger = internalLogger,
595-
executorService = contextExecutorService
600+
handler = broadcastReceiverHandler
596601
)
597602
systemInfoProvider.register(appContext)
598603

599604
// Network Info Provider
600-
setupNetworkInfoProviders(appContext)
605+
setupNetworkInfoProviders(appContext, broadcastReceiverHandler)
601606

602607
// User Info Provider
603608
userInfoProvider = DatadogUserInfoProvider()
@@ -606,7 +611,7 @@ internal class CoreFeature(
606611
accountInfoProvider = DatadogAccountInfoProvider(internalLogger)
607612
}
608613

609-
private fun setupNetworkInfoProviders(appContext: Context) {
614+
private fun setupNetworkInfoProviders(appContext: Context, broadcastReceiverHandler: Handler) {
610615
networkInfoProvider = if (buildSdkVersionProvider.isAtLeastN) {
611616
CallbackNetworkInfoProvider(
612617
internalLogger = internalLogger,
@@ -615,7 +620,7 @@ internal class CoreFeature(
615620
} else {
616621
BroadcastReceiverNetworkInfoProvider(
617622
internalLogger = internalLogger,
618-
executorService = contextExecutorService,
623+
handler = broadcastReceiverHandler,
619624
buildSdkVersionProvider = buildSdkVersionProvider
620625
)
621626
}
@@ -688,6 +693,9 @@ internal class CoreFeature(
688693
contextQueue,
689694
DatadogThreadFactory("context")
690695
)
696+
broadcastReceiverThread = BroadcastReceiverThread()
697+
@Suppress("UnsafeThirdPartyFunctionCall") // constructed once; start() is called exactly once here
698+
broadcastReceiverThread.start()
691699
}
692700

693701
private fun resolveProcessInfo(appContext: Context) {
@@ -718,6 +726,7 @@ internal class CoreFeature(
718726
uploadExecutorService.shutdownNow()
719727
contextExecutorService.shutdownNow()
720728
persistenceExecutorService.shutdownNow()
729+
broadcastReceiverThread.quitSafely()
721730

722731
try {
723732
uploadExecutorService.awaitTermination(1, TimeUnit.SECONDS)

0 commit comments

Comments
 (0)