From 67c3b7c7d45a6e612ca992cc5b3a97ce89588962 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Fri, 6 Nov 2026 13:37:11 +0100 Subject: [PATCH] ref(android): Fix Error Prone warnings in sentry-android-core Error Prone never ran on sentry-android-core. Enabling it reports 59 warnings outside Javadoc, which fail the build under -Werror. - Suppress FutureReturnValueIgnored, JavaUtilDate, and ReferenceEquality where identity is intended, as the sentry module does. - Keep the AnrProfilingIntegration updater a field, since removeCallbacks needs the instance that was posted, and suppress UnnecessaryLambda there. - Read the ANR thread dump and the app start profiling config as UTF-8, Android's default charset. - Remove unused fields and parameters, add missing @Override, make long-to-double conversions explicit, and narrow members that are effectively private or protected in a final class. - Explain the two catch blocks that ignore their exception. Co-Authored-By: Claude Opus 5.5 --- .../android/core/ActivityLifecycleIntegration.java | 1 + .../android/core/AndroidContinuousProfiler.java | 2 ++ .../io/sentry/android/core/AndroidFatalLogger.java | 8 ++------ .../android/core/AndroidLoggerBatchProcessor.java | 1 + .../android/core/AndroidMetricsBatchProcessor.java | 1 + .../android/core/AndroidOptionsInitializer.java | 2 +- .../java/io/sentry/android/core/AnrIntegration.java | 4 ++-- .../io/sentry/android/core/AnrV2Integration.java | 5 ++++- .../core/AppComponentsBreadcrumbsIntegration.java | 1 + .../core/ApplicationExitInfoEventProcessor.java | 2 ++ .../java/io/sentry/android/core/ContextUtils.java | 1 + .../sentry/android/core/CurrentActivityHolder.java | 2 ++ .../sentry/android/core/EnvelopeFileObserver.java | 2 +- .../core/EnvelopeFileObserverIntegration.java | 1 + .../android/core/FeedbackShakeIntegration.java | 4 ++++ .../java/io/sentry/android/core/Installation.java | 3 +-- .../io/sentry/android/core/InternalSentrySdk.java | 1 + .../io/sentry/android/core/LifecycleWatcher.java | 1 + .../main/java/io/sentry/android/core/LoadClass.java | 3 +++ .../android/core/MemoryLimiterIntegration.java | 1 + .../sentry/android/core/NativeEventCollector.java | 1 + .../android/core/NetworkBreadcrumbsIntegration.java | 5 +---- .../android/core/PerfettoContinuousProfiler.java | 2 ++ .../io/sentry/android/core/PerfettoProfiler.java | 1 + .../core/PerformanceAndroidEventProcessor.java | 3 --- .../java/io/sentry/android/core/SentryAndroid.java | 3 +-- .../android/core/SentryPerformanceProvider.java | 4 +++- .../sentry/android/core/SentryUserFeedbackForm.java | 3 +++ .../core/SystemEventsBreadcrumbsIntegration.java | 6 +++++- .../sentry/android/core/TombstoneIntegration.java | 1 + .../android/core/anr/AnrProfilingIntegration.java | 5 +++++ .../internal/gestures/SentryGestureListener.java | 1 + .../core/internal/modules/AssetsModulesLoader.java | 1 + .../android/core/internal/threaddump/Lines.java | 13 +++++++++---- .../util/AndroidConnectionStatusProvider.java | 5 +++-- .../internal/util/SentryFrameMetricsCollector.java | 3 +++ .../sentry/android/core/performance/TimeSpan.java | 4 ++-- 37 files changed, 75 insertions(+), 32 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java index 4ab9be82248..a435336b40b 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java @@ -459,6 +459,7 @@ void applyScope(final @NotNull IScope scope, final @NotNull ITransaction transac } @VisibleForTesting + @SuppressWarnings("ReferenceEquality") void clearScope(final @NotNull IScope scope, final @NotNull ITransaction transaction) { scope.withTransaction( scopeTransaction -> { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java index 4f115ca9d7f..8dc0b03d05d 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidContinuousProfiler.java @@ -335,6 +335,7 @@ private void stop(final boolean restartProfiler) { } } + @Override public void reevaluateSampling() { shouldSample = true; } @@ -373,6 +374,7 @@ public void close(final boolean isTerminating) { return ProfileRecordingState.UNKNOWN; } + @SuppressWarnings("FutureReturnValueIgnored") private void sendChunks(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { try { options diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidFatalLogger.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidFatalLogger.java index 76d6ba99784..3d7e46abf4d 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidFatalLogger.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidFatalLogger.java @@ -27,9 +27,9 @@ public void log( final @NotNull String message, final @Nullable Object... args) { if (args == null || args.length == 0) { - Log.println(toLogcatLevel(level), tag, message); + Log.println(Log.ASSERT, tag, message); } else { - Log.println(toLogcatLevel(level), tag, String.format(message, args)); + Log.println(Log.ASSERT, tag, String.format(message, args)); } } @@ -59,8 +59,4 @@ public void log( public boolean isEnabled(@Nullable SentryLevel level) { return true; } - - private int toLogcatLevel(final @NotNull SentryLevel sentryLevel) { - return Log.ASSERT; - } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidLoggerBatchProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidLoggerBatchProcessor.java index b81666e2f38..0eeb8bee1c8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidLoggerBatchProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidLoggerBatchProcessor.java @@ -23,6 +23,7 @@ public void onForeground() { } @Override + @SuppressWarnings("FutureReturnValueIgnored") public void onBackground() { if (!hasAcceptedItem) { return; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidMetricsBatchProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidMetricsBatchProcessor.java index d92c4369139..c224231daaa 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidMetricsBatchProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidMetricsBatchProcessor.java @@ -23,6 +23,7 @@ public void onForeground() { } @Override + @SuppressWarnings("FutureReturnValueIgnored") public void onBackground() { if (!hasAcceptedItem) { return; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java index 7c9004e5ad2..35bf157b697 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java @@ -491,7 +491,7 @@ static void installDefaultIntegrations( options.setReplayController(replay); } if (isDistributionAvailable) { - final DistributionIntegration distribution = new DistributionIntegration((context)); + final DistributionIntegration distribution = new DistributionIntegration(context); options.setDistributionController(distribution); options.addIntegration(distribution); } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java index b9fd0b781d8..1ff02fb9bd3 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java @@ -47,8 +47,7 @@ public AnrIntegration(final @NotNull Context context) { private @Nullable SentryOptions options; - protected static final @NotNull AutoClosableReentrantLock watchDogLock = - new AutoClosableReentrantLock(); + static final @NotNull AutoClosableReentrantLock watchDogLock = new AutoClosableReentrantLock(); @Override public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { @@ -56,6 +55,7 @@ public final void register(final @NotNull IScopes scopes, final @NotNull SentryO register(scopes, (SentryAndroidOptions) options); } + @SuppressWarnings("FutureReturnValueIgnored") private void register( final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { options diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java index 5e5500297f8..f57d4de7c14 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java @@ -38,6 +38,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.List; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -64,6 +65,7 @@ public AnrV2Integration(final @NotNull Context context) { @SuppressLint("NewApi") // we do the check in the AnrIntegrationFactory @Override + @SuppressWarnings("FutureReturnValueIgnored") public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = Objects.requireNonNull( @@ -210,7 +212,8 @@ public void markReported(final long timestamp) { } try (final BufferedReader reader = - new BufferedReader(new InputStreamReader(new ByteArrayInputStream(dump)))) { + new BufferedReader( + new InputStreamReader(new ByteArrayInputStream(dump), StandardCharsets.UTF_8))) { final Lines lines = Lines.readLines(reader); final ThreadDumpParser threadDumpParser = new ThreadDumpParser(options, isBackground); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java index e98c0afb2db..6dfcb888f3f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java @@ -169,6 +169,7 @@ private void captureConfigurationChangedBreadcrumb( } } + @SuppressWarnings("FutureReturnValueIgnored") private void executeInBackground(final @NotNull Runnable runnable) { if (options != null) { try { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ApplicationExitInfoEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/ApplicationExitInfoEventProcessor.java index 80da05967ea..a82a6de5db8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ApplicationExitInfoEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ApplicationExitInfoEventProcessor.java @@ -243,6 +243,7 @@ private boolean sampleReplay( return true; } + @SuppressWarnings("JavaUtilDate") private void setReplayId( final @NotNull SentryEvent event, final @NotNull OptionsSource optionsSource) { @Nullable String persistedReplayId = readFromDisk(options, REPLAY_FILENAME, String.class); @@ -933,6 +934,7 @@ private void setAnrExceptions( sentryExceptionFactory.getSentryExceptionsFromThread(mainThread, mechanism, anr)); } + @SuppressWarnings("JavaUtilDate") private void applyAnrProfile( @NotNull SentryEvent event, @NotNull Backfillable hint, diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ContextUtils.java b/sentry-android-core/src/main/java/io/sentry/android/core/ContextUtils.java index 60ae00f2ead..356fa5c0e76 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ContextUtils.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ContextUtils.java @@ -521,6 +521,7 @@ static void setAppPackageInfo( } } } catch (Throwable e) { + // Split APK info is optional, the app context is still complete without it. } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java index a7733821c05..23c3dcbc626 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java @@ -26,6 +26,7 @@ private CurrentActivityHolder() {} return null; } + @SuppressWarnings("ReferenceEquality") public void setActivity(final @NotNull Activity activity) { if (currentActivity != null && currentActivity.get() == activity) { return; @@ -38,6 +39,7 @@ public void clearActivity() { currentActivity = null; } + @SuppressWarnings("ReferenceEquality") public void clearActivity(final @NotNull Activity activity) { if (currentActivity != null && currentActivity.get() != activity) { return; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java index 4a3dc7a1786..b0da4dcdac6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java @@ -73,7 +73,7 @@ private static final class CachedEnvelopeHint private final long flushTimeoutMillis; private final @NotNull ILogger logger; - public CachedEnvelopeHint(final long flushTimeoutMillis, final @NotNull ILogger logger) { + CachedEnvelopeHint(final long flushTimeoutMillis, final @NotNull ILogger logger) { reset(); this.flushTimeoutMillis = flushTimeoutMillis; this.logger = Objects.requireNonNull(logger, "ILogger is required."); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java index ab95ae32daa..7966ca98d99 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserverIntegration.java @@ -30,6 +30,7 @@ public abstract class EnvelopeFileObserverIntegration implements Integration, Cl } @Override + @SuppressWarnings("FutureReturnValueIgnored") public final void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) { Objects.requireNonNull(scopes, "Scopes are required"); Objects.requireNonNull(options, "SentryOptions is required"); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/FeedbackShakeIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/FeedbackShakeIntegration.java index 4405cd19309..43341432c5f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/FeedbackShakeIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/FeedbackShakeIntegration.java @@ -78,6 +78,7 @@ public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions } @Override + @SuppressWarnings("FutureReturnValueIgnored") public synchronized void enableOnShake() { final @Nullable SentryAndroidOptions options = this.options; if (enabled || options == null) { @@ -154,6 +155,7 @@ void onDialogGone(final @NotNull Dialog dialog) { } } + @SuppressWarnings("ReferenceEquality") private boolean removeDialog(final @NotNull Dialog dialog) { boolean removed = false; for (final @NotNull VisibleDialog visibleDialog : visibleDialogs) { @@ -169,6 +171,7 @@ private boolean removeDialog(final @NotNull Dialog dialog) { return removed; } + @SuppressWarnings("ReferenceEquality") private boolean hasDialogOn(final @NotNull Activity activity) { for (final @NotNull VisibleDialog visibleDialog : visibleDialogs) { if (visibleDialog.dialogRef.get() != null && visibleDialog.activityRef.get() == activity) { @@ -226,6 +229,7 @@ public void onActivityResumed(final @NotNull Activity activity) { } @Override + @SuppressWarnings("ReferenceEquality") public void onActivityPaused(final @NotNull Activity activity) { // Only stop if this is the activity we're tracking. When transitioning between // activities, B.onResume may fire before A.onPause — stopping unconditionally diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/Installation.java b/sentry-android-core/src/main/java/io/sentry/android/core/Installation.java index ba08e71342a..fcd4406a5f8 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/Installation.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/Installation.java @@ -21,8 +21,7 @@ final class Installation { private static final Charset UTF_8 = Charset.forName("UTF-8"); - protected static final @NotNull AutoClosableReentrantLock staticLock = - new AutoClosableReentrantLock(); + static final @NotNull AutoClosableReentrantLock staticLock = new AutoClosableReentrantLock(); private Installation() {} diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java index 4ad11399d02..de5816420a2 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/InternalSentrySdk.java @@ -409,6 +409,7 @@ private static void addTimeSpanToSerializedSpans(TimeSpan span, ListTODO [MAJOR]: let a session remember the tick it started on, so this can use a {@link * Deadline} too. That tick must not be serialized. */ + @SuppressWarnings("JavaUtilDate") private boolean isSessionOnScopeStale() { final long nowMillis = TimeUnit.NANOSECONDS.toMillis(epochClock.now().epochNanos()); // No session, or one that never recorded a start, leaves nothing to resume. diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/LoadClass.java b/sentry-android-core/src/main/java/io/sentry/android/core/LoadClass.java index 34b8d1d5f19..58ae27ace83 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/LoadClass.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/LoadClass.java @@ -26,14 +26,17 @@ public LoadClass() { * @param logger an instance of ILogger * @return a Class if it's available, or null */ + @Override public @Nullable Class loadClass(final @NotNull String clazz, final @Nullable ILogger logger) { return delegate.loadClass(clazz, logger); } + @Override public boolean isClassAvailable(final @NotNull String clazz, final @Nullable ILogger logger) { return delegate.isClassAvailable(clazz, logger); } + @Override public boolean isClassAvailable( final @NotNull String clazz, final @Nullable SentryOptions options) { return delegate.isClassAvailable(clazz, options); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/MemoryLimiterIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/MemoryLimiterIntegration.java index f259250a733..83f5b680fe7 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/MemoryLimiterIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/MemoryLimiterIntegration.java @@ -107,6 +107,7 @@ public MemoryLimiterIntegration( } @Override + @SuppressWarnings("FutureReturnValueIgnored") public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { androidOptions = Objects.requireNonNull( diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/NativeEventCollector.java b/sentry-android-core/src/main/java/io/sentry/android/core/NativeEventCollector.java index 69dfa9c16be..bb7811ce594 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/NativeEventCollector.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/NativeEventCollector.java @@ -302,6 +302,7 @@ public boolean deleteNativeEventFile(final @NotNull NativeEventData nativeEventD * the fields we need and exits early once found. Uses a bounded stream to track position within * the payload and skip any unread bytes on close, avoiding allocation of the full payload. */ + @SuppressWarnings("JavaUtilDate") private @Nullable NativeEnvelopeMetadata extractMetadataFromEventPayload( final @NotNull InputStream stream, final int payloadLength, final @NotNull File file) { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java index c7f3182b97d..db0b02ea558 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/NetworkBreadcrumbsIntegration.java @@ -33,7 +33,6 @@ public final class NetworkBreadcrumbsIntegration implements Integration, Closeab private final @NotNull Context context; private final @NotNull BuildInfoProvider buildInfoProvider; private final @NotNull AutoClosableReentrantLock lock = new AutoClosableReentrantLock(); - private @Nullable SentryOptions options; @TestOnly @Nullable volatile NetworkBreadcrumbsNetworkCallback networkCallback; @@ -53,8 +52,6 @@ public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions (options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null, "SentryAndroidOptions is required"); - this.options = options; - options .getLogger() .log( @@ -237,7 +234,7 @@ boolean isSimilar(final @NotNull NetworkBreadcrumbConnectionDetail other) { // This means that if the new connection detail come less than 5 seconds after the previous // one, we'll report the signal and bandwidth as similar, regardless of their real value. boolean isTimestampSimilar = - DateUtils.nanosToMillis(Math.abs(timestampNanos - other.timestampNanos)) < 5000; + DateUtils.nanosToMillis((double) Math.abs(timestampNanos - other.timestampNanos)) < 5000; boolean isSignalSimilar = isTimestampSimilar || signalDiff <= 5; boolean isDownBandwidthSimilar = isTimestampSimilar || downBandwidthDiff <= Math.max(1000, Math.abs(downBandwidth) * 0.1); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoContinuousProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoContinuousProfiler.java index 15ae88f22c8..baa7af2683d 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoContinuousProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoContinuousProfiler.java @@ -527,12 +527,14 @@ private void onChunkCollected( } } + @Override public void reevaluateSampling() { try (final @NotNull ISentryLifecycleToken ignored = lock.acquire()) { shouldSample = true; } } + @SuppressWarnings("FutureReturnValueIgnored") private void sendChunk( final @NotNull ProfileChunk.Builder builder, final @NotNull IScopes scopes, diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoProfiler.java b/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoProfiler.java index 627a434d6f3..36248da64ad 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoProfiler.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/PerfettoProfiler.java @@ -123,6 +123,7 @@ boolean start(final @NotNull ChunkRecord chunkRecord, final long durationMs) { * error) once the OS delivers the result. The listener may be called synchronously if the result * has already arrived, or asynchronously on an OS-managed thread otherwise. */ + @SuppressWarnings("FutureReturnValueIgnored") public void endAndCollect(final @NotNull Consumer<@Nullable File> listener) { if (!started) { logger.log(SentryLevel.WARNING, "PerfettoProfiler was never started"); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java index aff50c99340..47404d43333 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/PerformanceAndroidEventProcessor.java @@ -40,13 +40,10 @@ final class PerformanceAndroidEventProcessor implements SentryEventProcessor { private static final String APP_METRICS_ORIGIN = "auto.ui"; private static final String APP_METRICS_CONTENT_PROVIDER_OP = "contentprovider.load"; - private static final String APP_METRICS_ACTIVITIES_OP = "activity.load"; private static final String APP_METRICS_APPLICATION_OP = "application.load"; private static final String APP_METRICS_PROCESS_INIT_OP = "process.load"; private static final long MAX_PROCESS_INIT_APP_START_DIFF_MS = 10000; - private boolean sentStartMeasurement = false; - private final @NotNull SentryAndroidOptions options; private final @NotNull AutoClosableReentrantLock lock = new AutoClosableReentrantLock(); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java index e649e9e094c..7e1df235714 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java @@ -48,8 +48,7 @@ public final class SentryAndroid { private static final String FRAGMENT_CLASS_NAME = "androidx.fragment.app.FragmentManager$FragmentLifecycleCallbacks"; - protected static final @NotNull AutoClosableReentrantLock staticLock = - new AutoClosableReentrantLock(); + static final @NotNull AutoClosableReentrantLock staticLock = new AutoClosableReentrantLock(); private SentryAndroid() {} diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java index 9d1f2e13ec4..427eefd7e48 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java @@ -29,6 +29,7 @@ import java.io.FileNotFoundException; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.StandardCharsets; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -115,7 +116,8 @@ private void launchAppStartProfiler(final @NotNull AppStartMetrics appStartMetri } try (final @NotNull Reader reader = - new BufferedReader(new InputStreamReader(new FileInputStream(configFile)))) { + new BufferedReader( + new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8))) { final @Nullable SentryAppStartProfilingOptions profilingOptions = deserializeProfilingConfig(reader); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java index 999fad1227e..ef13fbaf683 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryUserFeedbackForm.java @@ -179,6 +179,7 @@ private class ShakeLifecycleCallbacks implements Application.ActivityLifecycleCa } @Override + @SuppressWarnings("ReferenceEquality") public void onActivityResumed(final @NotNull Activity activity) { if (activity == activityRef.get() && shakeDetector != null) { shakeDetector.start(activity, shakeListener(activityRef)); @@ -186,6 +187,7 @@ public void onActivityResumed(final @NotNull Activity activity) { } @Override + @SuppressWarnings("ReferenceEquality") public void onActivityPaused(final @NotNull Activity activity) { if (activity == activityRef.get() && shakeDetector != null) { shakeDetector.stop(); @@ -193,6 +195,7 @@ public void onActivityPaused(final @NotNull Activity activity) { } @Override + @SuppressWarnings("ReferenceEquality") public void onActivityDestroyed(final @NotNull Activity activity) { if (activity == activityRef.get()) { stopShakeDetection(); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java index 3f45a9a9fb8..402a0b35cac 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java @@ -124,6 +124,7 @@ public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions } } + @SuppressWarnings("FutureReturnValueIgnored") private void registerReceiver( final @NotNull IScopes scopes, final @NotNull SentryAndroidOptions options) { @@ -196,7 +197,10 @@ private void registerReceiver( } } - @SuppressWarnings("Convert2MethodRef") // older AGP versions do not support method references + @SuppressWarnings({ + "Convert2MethodRef", + "FutureReturnValueIgnored" + }) // older AGP versions do not support method references private void scheduleUnregisterReceiver() { if (options == null) { return; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/TombstoneIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/TombstoneIntegration.java index 43de4034ec5..a914d924c40 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/TombstoneIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/TombstoneIntegration.java @@ -67,6 +67,7 @@ public TombstoneIntegration(final @NotNull Context context) { } @Override + @SuppressWarnings("FutureReturnValueIgnored") public void register(@NotNull IScopes scopes, @NotNull SentryOptions options) { this.options = Objects.requireNonNull( diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrProfilingIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrProfilingIntegration.java index bc41f3faf6a..10a75a08974 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrProfilingIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrProfilingIntegration.java @@ -44,7 +44,11 @@ public class AnrProfilingIntegration static final int MAX_NUM_STACKS = (int) (10_000 / POLLING_INTERVAL_MS); private final AtomicBoolean enabled = new AtomicBoolean(true); + + // A field rather than a method reference, as removeCallbacks only removes the posted instance. + @SuppressWarnings("UnnecessaryLambda") private final Runnable updater = () -> lastMainThreadExecutionTime = SystemClock.uptimeMillis(); + private final @NotNull AutoClosableReentrantLock lifecycleLock = new AutoClosableReentrantLock(); private final @NotNull AutoClosableReentrantLock profileManagerLock = new AutoClosableReentrantLock(); @@ -87,6 +91,7 @@ public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions } @Override + @SuppressWarnings("FutureReturnValueIgnored") public void close() throws IOException { enabled.set(false); AppState.getInstance().removeAppStateListener(this); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java index 61a32b675db..12ca130be9e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/gestures/SentryGestureListener.java @@ -314,6 +314,7 @@ void stopTracing(final @NotNull SpanStatus status) { } @VisibleForTesting + @SuppressWarnings("ReferenceEquality") void clearScope(final @NotNull IScope scope) { scope.withTransaction( transaction -> { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java index 1aa8a89f8fc..ea94ea8e262 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/modules/AssetsModulesLoader.java @@ -18,6 +18,7 @@ public final class AssetsModulesLoader extends ModulesLoader { private final @NotNull Context context; + @SuppressWarnings("FutureReturnValueIgnored") public AssetsModulesLoader(final @NotNull Context context, final @NotNull SentryOptions options) { super(options.getLogger()); this.context = ContextUtils.getApplicationContext(context); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/threaddump/Lines.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/threaddump/Lines.java index 5c314e1b23f..15f9d7251de 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/threaddump/Lines.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/threaddump/Lines.java @@ -20,9 +20,12 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.List; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,7 +35,7 @@ */ @ApiStatus.Internal public final class Lines { - private final @NotNull ArrayList mList; + private final @NotNull List mList; private final int mMin; private final int mMax; @@ -41,7 +44,9 @@ public final class Lines { /** Read the whole file into a Lines object. */ public static Lines readLines(final @NotNull File file) throws IOException { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + try (BufferedReader reader = + new BufferedReader( + new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { return Lines.readLines(reader); } } @@ -61,7 +66,7 @@ public static Lines readLines(final @NotNull BufferedReader in) throws IOExcepti } /** Construct with a list of lines. */ - public Lines(final @NotNull ArrayList list) { + public Lines(final @NotNull List list) { this.mList = list; mMin = 0; mMax = mList.size(); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/AndroidConnectionStatusProvider.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/AndroidConnectionStatusProvider.java index 62a212e6dcc..59919d7c184 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/AndroidConnectionStatusProvider.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/AndroidConnectionStatusProvider.java @@ -276,7 +276,7 @@ public void onCapabilitiesChanged( if (!network.equals(currentNetwork)) { return; } - updateCacheAndNotifyObservers(network, networkCapabilities); + updateCacheAndNotifyObservers(networkCapabilities); try (final @NotNull ISentryLifecycleToken ignored = childCallbacksLock.acquire()) { for (final @NotNull NetworkCallback cb : childCallbacks) { @@ -286,7 +286,7 @@ public void onCapabilitiesChanged( } private void updateCacheAndNotifyObservers( - @Nullable Network network, @Nullable NetworkCapabilities networkCapabilities) { + @Nullable NetworkCapabilities networkCapabilities) { // Check if this change is meaningful before notifying observers final boolean shouldUpdate = isSignificantChange(networkCapabilities); @@ -847,6 +847,7 @@ public static List getChildCallbacks() { return childCallbacks; } + @SuppressWarnings("FutureReturnValueIgnored") private void submitSafe(@NotNull Runnable r) { try { options.getExecutorService().submit(r); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/SentryFrameMetricsCollector.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/SentryFrameMetricsCollector.java index 2c0ae246558..fd9f92db49e 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/SentryFrameMetricsCollector.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/SentryFrameMetricsCollector.java @@ -269,6 +269,7 @@ public void onActivityResumed(@NotNull Activity activity) {} public void onActivityPaused(@NotNull Activity activity) {} @Override + @SuppressWarnings("ReferenceEquality") public void onActivityStopped(@NotNull Activity activity) { stopTrackingWindow(activity.getWindow()); if (currentWindow != null && currentWindow.get() == activity.getWindow()) { @@ -345,6 +346,7 @@ private void stopTrackingWindow(final @NotNull Window window) { }); } + @SuppressWarnings("ReferenceEquality") private void setCurrentWindow(final @NotNull Window window) { if (currentWindow != null && currentWindow.get() == window) { return; @@ -395,6 +397,7 @@ public long getLastKnownFrameStartTimeNanos() { return choreographerFrameStartTime; } } catch (IllegalAccessException ignored) { + // The frame start time is unknown then, same as when the field is missing. } } return -1; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/performance/TimeSpan.java b/sentry-android-core/src/main/java/io/sentry/android/core/performance/TimeSpan.java index 5ea785165dc..c6108656661 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/performance/TimeSpan.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/performance/TimeSpan.java @@ -103,7 +103,7 @@ public long getStartTimestampMs() { * @return the start timestamp of this measurement, unix time, in seconds */ public double getStartTimestampSecs() { - return DateUtils.millisToSeconds(startUnixTimeMs); + return DateUtils.millisToSeconds((double) startUnixTimeMs); } /** @@ -123,7 +123,7 @@ public long getProjectedStopTimestampMs() { * @see #getProjectedStopTimestampMs() */ public double getProjectedStopTimestampSecs() { - return DateUtils.millisToSeconds(getProjectedStopTimestampMs()); + return DateUtils.millisToSeconds((double) getProjectedStopTimestampMs()); } /**