Skip to content

Commit 96aa016

Browse files
authored
Merge branch 'main' into dependabot/github_actions/github/codeql-action-3.28.15
2 parents f6fa462 + 6df3ba5 commit 96aa016

File tree

52 files changed

+1211
-199
lines changed

Some content is hidden

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

52 files changed

+1211
-199
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,32 @@
22

33
## Unreleased
44

5+
### Fixes
6+
7+
- Update profile chunk rate limit and client report ([#4353](https://github.com/getsentry/sentry-java/pull/4353))
8+
9+
## 8.9.0
10+
11+
### Features
12+
13+
- Add `SentryWrapper.wrapRunnable` to wrap `Runnable` for use with Sentry ([#4332](https://github.com/getsentry/sentry-java/pull/4332))
14+
15+
### Fixes
16+
17+
- Fix TTFD measurement when API called too early ([#4297](https://github.com/getsentry/sentry-java/pull/4297))
18+
- Tag sockets traffic originating from Sentry's HttpConnection ([#4340](https://github.com/getsentry/sentry-java/pull/4340))
19+
- This should suppress the StrictMode's `UntaggedSocketViolation`
20+
- Reduce debug logs verbosity ([#4341](https://github.com/getsentry/sentry-java/pull/4341))
21+
- Fix unregister `SystemEventsBroadcastReceiver` when entering background ([#4338](https://github.com/getsentry/sentry-java/pull/4338))
22+
- This should reduce ANRs seen with this class in the stack trace for Android 14 and above
23+
24+
### Improvements
25+
26+
- Make user interaction tracing faster and do fewer allocations ([#4347](https://github.com/getsentry/sentry-java/pull/4347))
27+
- Pre-load modules on a background thread upon SDK init ([#4348](https://github.com/getsentry/sentry-java/pull/4348))
28+
29+
## 8.8.0
30+
531
### Features
632

733
- Add `CoroutineExceptionHandler` for reporting uncaught exceptions in coroutines to Sentry ([#4259](https://github.com/getsentry/sentry-java/pull/4259))
@@ -15,6 +41,11 @@
1541
- This ensures correct resource loading in environments like Spring Boot where the thread context classloader is used for resource loading.
1642
- Improve low memory breadcrumb capturing ([#4325](https://github.com/getsentry/sentry-java/pull/4325))
1743
- Fix do not initialize SDK for Jetpack Compose Preview builds ([#4324](https://github.com/getsentry/sentry-java/pull/4324))
44+
- Fix Synchronize Baggage values ([#4327](https://github.com/getsentry/sentry-java/pull/4327))
45+
46+
### Improvements
47+
48+
- Make `SystemEventsBreadcrumbsIntegration` faster ([#4330](https://github.com/getsentry/sentry-java/pull/4330))
1849

1950
## 8.7.0
2051

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ org.gradle.workers.max=2
1414
android.useAndroidX=true
1515

1616
# Release information
17-
versionName=8.7.0
17+
versionName=8.9.0
1818

1919
# Override the SDK name on native crashes on Android
2020
sentryAndroidSdkName=sentry.native.android

scripts/toggle-codec-logs.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/bin/bash
2+
3+
# --- Functions ---
4+
5+
print_usage() {
6+
echo "Usage: $0 [enable|disable]"
7+
exit 1
8+
}
9+
10+
# Check for adb
11+
if ! command -v adb &> /dev/null; then
12+
echo "❌ adb not found. Please install Android Platform Tools and ensure adb is in your PATH."
13+
exit 1
14+
fi
15+
16+
# Check for connected device
17+
DEVICE_COUNT=$(adb devices | grep -w "device" | wc -l)
18+
if [ "$DEVICE_COUNT" -eq 0 ]; then
19+
echo "❌ No device connected. Please connect a device and enable USB debugging."
20+
exit 1
21+
fi
22+
23+
# --- Handle Argument ---
24+
25+
ACTION=$(echo "$1" | tr '[:upper:]' '[:lower:]')
26+
27+
case "$ACTION" in
28+
enable)
29+
echo "✅ Enabling native logs (DEBUG)..."
30+
adb shell setprop log.tag.MPEG4Writer D
31+
adb shell setprop log.tag.CCodec D
32+
adb shell setprop log.tag.VQApply D
33+
adb shell setprop log.tag.ColorUtils D
34+
adb shell setprop log.tag.MediaCodec D
35+
adb shell setprop log.tag.MediaCodecList D
36+
adb shell setprop log.tag.MediaWriter D
37+
adb shell setprop log.tag.CCodecConfig D
38+
adb shell setprop log.tag.Codec2Client D
39+
adb shell setprop log.tag.CCodecBufferChannel D
40+
adb shell setprop log.tag.CodecProperties D
41+
adb shell setprop log.tag.CodecSeeding D
42+
adb shell setprop log.tag.C2Store D
43+
adb shell setprop log.tag.C2NodeImpl D
44+
adb shell setprop log.tag.GraphicBufferSource D
45+
adb shell setprop log.tag.BufferQueueProducer D
46+
adb shell setprop log.tag.ReflectedParamUpdater D
47+
adb shell setprop log.tag.hw-BpHwBinder D
48+
echo "✅ Logs ENABLED"
49+
;;
50+
disable)
51+
echo "🚫 Disabling native logs (SILENT)..."
52+
adb shell setprop log.tag.MPEG4Writer SILENT
53+
adb shell setprop log.tag.CCodec SILENT
54+
adb shell setprop log.tag.VQApply SILENT
55+
adb shell setprop log.tag.ColorUtils SILENT
56+
adb shell setprop log.tag.MediaCodec SILENT
57+
adb shell setprop log.tag.MediaCodecList SILENT
58+
adb shell setprop log.tag.MediaWriter SILENT
59+
adb shell setprop log.tag.CCodecConfig SILENT
60+
adb shell setprop log.tag.Codec2Client SILENT
61+
adb shell setprop log.tag.CCodecBufferChannel SILENT
62+
adb shell setprop log.tag.CodecProperties SILENT
63+
adb shell setprop log.tag.CodecSeeding SILENT
64+
adb shell setprop log.tag.C2Store SILENT
65+
adb shell setprop log.tag.C2NodeImpl SILENT
66+
adb shell setprop log.tag.GraphicBufferSource SILENT
67+
adb shell setprop log.tag.BufferQueueProducer SILENT
68+
adb shell setprop log.tag.ReflectedParamUpdater SILENT
69+
adb shell setprop log.tag.hw-BpHwBinder SILENT
70+
echo "🚫 Logs DISABLED"
71+
;;
72+
*)
73+
echo "❓ Unknown or missing argument: '$1'"
74+
print_usage
75+
;;
76+
esac

sentry-android-core/api/sentry-android-core.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ public class io/sentry/android/core/AndroidProfiler$ProfileStartData {
111111
public fun <init> (JJLjava/util/Date;)V
112112
}
113113

114+
public final class io/sentry/android/core/AndroidSocketTagger : io/sentry/ISocketTagger {
115+
public static fun getInstance ()Lio/sentry/android/core/AndroidSocketTagger;
116+
public fun tagSockets ()V
117+
public fun untagSockets ()V
118+
}
119+
114120
public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable {
115121
public fun <init> (Landroid/content/Context;)V
116122
public fun close ()V

sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ public final class ActivityLifecycleIntegration
9191

9292
private final @NotNull ActivityFramesTracker activityFramesTracker;
9393
private final @NotNull AutoClosableReentrantLock lock = new AutoClosableReentrantLock();
94+
private boolean fullyDisplayedCalled = false;
95+
private final @NotNull AutoClosableReentrantLock fullyDisplayedLock =
96+
new AutoClosableReentrantLock();
9497

9598
public ActivityLifecycleIntegration(
9699
final @NotNull Application application,
@@ -413,12 +416,17 @@ public void onActivityCreated(
413416
scopes.configureScope(scope -> scope.setScreen(activityClassName));
414417
}
415418
startTracing(activity);
419+
final @Nullable ISpan ttidSpan = ttidSpanMap.get(activity);
416420
final @Nullable ISpan ttfdSpan = ttfdSpanMap.get(activity);
417421

418422
firstActivityCreated = true;
419423

420-
if (performanceEnabled && ttfdSpan != null && fullyDisplayedReporter != null) {
421-
fullyDisplayedReporter.registerFullyDrawnListener(() -> onFullFrameDrawn(ttfdSpan));
424+
if (performanceEnabled
425+
&& ttidSpan != null
426+
&& ttfdSpan != null
427+
&& fullyDisplayedReporter != null) {
428+
fullyDisplayedReporter.registerFullyDrawnListener(
429+
() -> onFullFrameDrawn(ttidSpan, ttfdSpan));
422430
}
423431
}
424432
}
@@ -635,37 +643,59 @@ private void onFirstFrameDrawn(final @Nullable ISpan ttfdSpan, final @Nullable I
635643
}
636644
finishAppStartSpan();
637645

638-
if (options != null && ttidSpan != null) {
639-
final SentryDate endDate = options.getDateProvider().now();
640-
final long durationNanos = endDate.diff(ttidSpan.getStartDate());
641-
final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
642-
ttidSpan.setMeasurement(
643-
MeasurementValue.KEY_TIME_TO_INITIAL_DISPLAY, durationMillis, MILLISECOND);
644-
645-
if (ttfdSpan != null && ttfdSpan.isFinished()) {
646-
ttfdSpan.updateEndDate(endDate);
647-
// If the ttfd span was finished before the first frame we adjust the measurement, too
646+
// Sentry.reportFullyDisplayed can be run in any thread, so we have to ensure synchronization
647+
// with first frame drawn
648+
try (final @NotNull ISentryLifecycleToken ignored = fullyDisplayedLock.acquire()) {
649+
if (options != null && ttidSpan != null) {
650+
final SentryDate endDate = options.getDateProvider().now();
651+
final long durationNanos = endDate.diff(ttidSpan.getStartDate());
652+
final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
648653
ttidSpan.setMeasurement(
649-
MeasurementValue.KEY_TIME_TO_FULL_DISPLAY, durationMillis, MILLISECOND);
654+
MeasurementValue.KEY_TIME_TO_INITIAL_DISPLAY, durationMillis, MILLISECOND);
655+
// If Sentry.reportFullyDisplayed was called before the first frame is drawn, we finish
656+
// the ttfd now
657+
if (ttfdSpan != null && fullyDisplayedCalled) {
658+
fullyDisplayedCalled = false;
659+
ttidSpan.setMeasurement(
660+
MeasurementValue.KEY_TIME_TO_FULL_DISPLAY, durationMillis, MILLISECOND);
661+
ttfdSpan.setMeasurement(
662+
MeasurementValue.KEY_TIME_TO_FULL_DISPLAY, durationMillis, MILLISECOND);
663+
finishSpan(ttfdSpan, endDate);
664+
}
665+
666+
finishSpan(ttidSpan, endDate);
667+
} else {
668+
finishSpan(ttidSpan);
669+
if (fullyDisplayedCalled) {
670+
finishSpan(ttfdSpan);
671+
}
650672
}
651-
finishSpan(ttidSpan, endDate);
652-
} else {
653-
finishSpan(ttidSpan);
654673
}
655674
}
656675

657-
private void onFullFrameDrawn(final @Nullable ISpan ttfdSpan) {
658-
if (options != null && ttfdSpan != null) {
659-
final SentryDate endDate = options.getDateProvider().now();
660-
final long durationNanos = endDate.diff(ttfdSpan.getStartDate());
661-
final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
662-
ttfdSpan.setMeasurement(
663-
MeasurementValue.KEY_TIME_TO_FULL_DISPLAY, durationMillis, MILLISECOND);
664-
finishSpan(ttfdSpan, endDate);
665-
} else {
666-
finishSpan(ttfdSpan);
667-
}
676+
private void onFullFrameDrawn(final @NotNull ISpan ttidSpan, final @NotNull ISpan ttfdSpan) {
668677
cancelTtfdAutoClose();
678+
// Sentry.reportFullyDisplayed can be run in any thread, so we have to ensure synchronization
679+
// with first frame drawn
680+
try (final @NotNull ISentryLifecycleToken ignored = fullyDisplayedLock.acquire()) {
681+
// If the TTID span didn't finish, it means the first frame was not drawn yet, which means
682+
// Sentry.reportFullyDisplayed was called too early. We set a flag, so that whenever the TTID
683+
// will finish, we will finish the TTFD span as well.
684+
if (!ttidSpan.isFinished()) {
685+
fullyDisplayedCalled = true;
686+
return;
687+
}
688+
if (options != null) {
689+
final SentryDate endDate = options.getDateProvider().now();
690+
final long durationNanos = endDate.diff(ttfdSpan.getStartDate());
691+
final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
692+
ttfdSpan.setMeasurement(
693+
MeasurementValue.KEY_TIME_TO_FULL_DISPLAY, durationMillis, MILLISECOND);
694+
finishSpan(ttfdSpan, endDate);
695+
} else {
696+
finishSpan(ttfdSpan);
697+
}
698+
}
669699
}
670700

671701
private void finishExceededTtfdSpan(

sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private void start() {
178178
final @Nullable RateLimiter rateLimiter = scopes.getRateLimiter();
179179
if (rateLimiter != null
180180
&& (rateLimiter.isActiveForCategory(All)
181-
|| rateLimiter.isActiveForCategory(DataCategory.ProfileChunk))) {
181+
|| rateLimiter.isActiveForCategory(DataCategory.ProfileChunkUi))) {
182182
logger.log(SentryLevel.WARNING, "SDK is rate limited. Stopping profiler.");
183183
// Let's stop and reset profiler id, as the profile is now broken anyway
184184
stop(false);
@@ -385,7 +385,7 @@ public int getRootSpanCounter() {
385385
public void onRateLimitChanged(@NotNull RateLimiter rateLimiter) {
386386
// We stop the profiler as soon as we are rate limited, to avoid the performance overhead
387387
if (rateLimiter.isActiveForCategory(All)
388-
|| rateLimiter.isActiveForCategory(DataCategory.ProfileChunk)) {
388+
|| rateLimiter.isActiveForCategory(DataCategory.ProfileChunkUi)) {
389389
logger.log(SentryLevel.WARNING, "SDK is rate limited. Stopping profiler.");
390390
stop(false);
391391
}

sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.sentry.NoOpCompositePerformanceCollector;
1616
import io.sentry.NoOpConnectionStatusProvider;
1717
import io.sentry.NoOpContinuousProfiler;
18+
import io.sentry.NoOpSocketTagger;
1819
import io.sentry.NoOpTransactionProfiler;
1920
import io.sentry.NoopVersionDetector;
2021
import io.sentry.ScopeType;
@@ -238,6 +239,9 @@ static void initializeIntegrationsAndProcessors(
238239
if (options.getThreadChecker() instanceof NoOpThreadChecker) {
239240
options.setThreadChecker(AndroidThreadChecker.getInstance());
240241
}
242+
if (options.getSocketTagger() instanceof NoOpSocketTagger) {
243+
options.setSocketTagger(AndroidSocketTagger.getInstance());
244+
}
241245
if (options.getPerformanceCollectors().isEmpty()) {
242246
options.addPerformanceCollector(new AndroidMemoryCollector());
243247
options.addPerformanceCollector(new AndroidCpuCollector(options.getLogger()));
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.sentry.android.core;
2+
3+
import android.net.TrafficStats;
4+
import io.sentry.ISocketTagger;
5+
import org.jetbrains.annotations.ApiStatus;
6+
7+
@ApiStatus.Internal
8+
public final class AndroidSocketTagger implements ISocketTagger {
9+
10+
// just a random number to tag outgoing traffic from the Sentry SDK
11+
private static final int SENTRY_TAG = 0xF001;
12+
13+
private static final AndroidSocketTagger instance = new AndroidSocketTagger();
14+
15+
private AndroidSocketTagger() {}
16+
17+
public static AndroidSocketTagger getInstance() {
18+
return instance;
19+
}
20+
21+
@Override
22+
public void tagSockets() {
23+
TrafficStats.setThreadStatsTag(SENTRY_TAG);
24+
}
25+
26+
@Override
27+
public void untagSockets() {
28+
TrafficStats.clearThreadStatsTag();
29+
}
30+
}

sentry-android-core/src/main/java/io/sentry/android/core/AppLifecycleIntegration.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,8 @@ public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions
6969
options
7070
.getLogger()
7171
.log(
72-
SentryLevel.INFO,
73-
"androidx.lifecycle is not available, AppLifecycleIntegration won't be installed",
74-
e);
72+
SentryLevel.WARNING,
73+
"androidx.lifecycle is not available, AppLifecycleIntegration won't be installed");
7574
} catch (IllegalStateException e) {
7675
options
7776
.getLogger()

sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ final class ManifestMetadataReader {
109109

110110
static final String REPLAYS_MASK_ALL_IMAGES = "io.sentry.session-replay.mask-all-images";
111111

112+
static final String REPLAYS_DEBUG = "io.sentry.session-replay.debug";
113+
112114
static final String FORCE_INIT = "io.sentry.force-init";
113115

114116
static final String MAX_BREADCRUMBS = "io.sentry.max-breadcrumbs";
@@ -452,6 +454,8 @@ static void applyMetadata(
452454
.getSessionReplay()
453455
.setMaskAllImages(readBool(metadata, logger, REPLAYS_MASK_ALL_IMAGES, true));
454456

457+
options.getSessionReplay().setDebug(readBool(metadata, logger, REPLAYS_DEBUG, false));
458+
455459
options.setIgnoredErrors(readList(metadata, logger, IGNORED_ERRORS));
456460

457461
final @Nullable List<String> includes = readList(metadata, logger, IN_APP_INCLUDES);

0 commit comments

Comments
 (0)