Skip to content

Commit 033ce52

Browse files
runningcodeclaude
andauthored
ref(android): Deprecate AndroidCurrentDateProvider (JAVA-728) (#6103)
* ref(android): Deprecate AndroidCurrentDateProvider (JAVA-728) AndroidCurrentDateProvider.getCurrentTimeMillis() is SystemClock.uptimeMillis(): not a date, and not a clock that counts deep sleep. Neither the name nor the ICurrentDateProvider type says so, and CurrentDateProvider implements that same interface with epoch milliseconds, so a call site declaring the interface accepts either and the two disagree by however long the device has been suspended. MonotonicTicker names the guarantee it gives and keeps counting through deep sleep. The annotation goes on getInstance() rather than on the type. The Android modules compile at Java 8, where javac still warns on an import of a deprecated type, and an import declaration cannot carry a @SuppressWarnings. Deprecating the sole factory method warns every caller just the same, and each warning lands somewhere a suppression can go. Nothing is migrated and nothing is removed. The five suppressed call sites are the migration list. AndroidEnvelopeCache cannot move on its own: it subtracts TimeSpan.getStartUptimeMs(), which is SystemClock.uptimeMillis() too, so moving one operand alone would subtract two different clock bases. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * changelog * ref(android): Deprecate the whole AndroidCurrentDateProvider type (JAVA-728) Deprecating the type rather than getInstance() says the hazard is the class itself, and warns on every mention of it, the import included. That is only affordable because this class has five use sites. An import of a deprecated type still warns at Java 8 (JEP 211 elides those only from source 9 on), -Werror turns it into an error, and an import declaration cannot carry a @SuppressWarnings. Dropping the five imports for fully-qualified names puts every reference inside a declaration that a suppression can cover. Verified by re-adding one import: the build fails with "warning: [deprecation] AndroidCurrentDateProvider in io.sentry.android.core.internal.util has been deprecated". The suppression comments now point at JAVA-729, which tracks migrating the call sites, rather than restating the reasoning at each one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * changelog * ref(android): Move the deprecation back onto getInstance() (JAVA-728) Deprecating the type required replacing all five imports with fully qualified names, since an import of a deprecated type warns at Java 8 and an import cannot carry a @SuppressWarnings. That churn bought nothing. The constructor is private, so getInstance() is the only way into this class and deprecating it warns every real caller identically. Type-level deprecation would only add a warning for declaring a variable of the concrete type, which nothing does: every holder declares ICurrentDateProvider. Measured the alternatives before reverting. Neither a class-level @SuppressWarnings nor a static import silences the import warning; only a fully qualified name, or a reference from inside the type's own package, avoids it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * changelog --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent e907d8d commit 033ce52

7 files changed

Lines changed: 31 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
- Sentry can now configure Log4j2 automatically for Spring Boot 3 when `sentry-log4j2` is on the classpath and Log4j2 Core is the active logging backend ([#6072](https://github.com/getsentry/sentry-java/pull/6072))
3535
- Disabled by default for now; enable it and configure levels the same way as described in the Spring Boot 4 entry above (`sentry.logging.enabled=true`)
3636

37+
### Internal
38+
39+
- Deprecate `AndroidCurrentDateProvider.getInstance()` in favor of `MonotonicTicker`, which counts time spent in deep sleep and cannot be confused with the epoch-based `CurrentDateProvider` ([#6103](https://github.com/getsentry/sentry-java/pull/6103))
40+
3741
## 8.56.0
3842

3943
### Behavioral Changes

‎sentry-android-core/src/main/java/io/sentry/android/core/AppComponentsBreadcrumbsIntegration.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public final class AppComponentsBreadcrumbsIntegration
3434
private @Nullable IScopes scopes;
3535
private @Nullable SentryAndroidOptions options;
3636

37+
// TODO: JAVA-729
38+
@SuppressWarnings("deprecation")
3739
private final @NotNull Debouncer trimMemoryDebouncer =
3840
new Debouncer(AndroidCurrentDateProvider.getInstance(), DEBOUNCE_WAIT_TIME_MS, 0);
3941

‎sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public final class ScreenshotEventProcessor implements EventProcessor {
4747
private final boolean isReplayAvailable;
4848
private final AtomicBoolean isReplayModuleAbsenceLogged = new AtomicBoolean(false);
4949

50+
// TODO: JAVA-729
51+
@SuppressWarnings("deprecation")
5052
public ScreenshotEventProcessor(
5153
final @NotNull SentryAndroidOptions options,
5254
final @NotNull BuildInfoProvider buildInfoProvider,

‎sentry-android-core/src/main/java/io/sentry/android/core/SystemEventsBreadcrumbsIntegration.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ final class SystemEventsBroadcastReceiver extends BroadcastReceiver {
298298
private static final long DEBOUNCE_WAIT_TIME_MS = 60 * 1000;
299299
private final @NotNull IScopes scopes;
300300
private final @NotNull SentryAndroidOptions options;
301+
302+
// TODO: JAVA-729
303+
@SuppressWarnings("deprecation")
301304
private final @NotNull Debouncer batteryChangedDebouncer =
302305
new Debouncer(AndroidCurrentDateProvider.getInstance(), DEBOUNCE_WAIT_TIME_MS, 0);
303306

‎sentry-android-core/src/main/java/io/sentry/android/core/ViewHierarchyEventProcessor.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public final class ViewHierarchyEventProcessor implements EventProcessor {
4646
private static final long DEBOUNCE_WAIT_TIME_MS = 2000;
4747
private static final int DEBOUNCE_MAX_EXECUTIONS = 3;
4848

49+
// TODO: JAVA-729
50+
@SuppressWarnings("deprecation")
4951
public ViewHierarchyEventProcessor(final @NotNull SentryAndroidOptions options) {
5052
this.options = Objects.requireNonNull(options, "SentryAndroidOptions is required");
5153
this.debouncer =

‎sentry-android-core/src/main/java/io/sentry/android/core/cache/AndroidEnvelopeCache.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public final class AndroidEnvelopeCache extends EnvelopeCache {
3838

3939
private final @NotNull ICurrentDateProvider currentDateProvider;
4040

41+
// TODO: JAVA-729
42+
@SuppressWarnings("deprecation")
4143
public AndroidEnvelopeCache(final @NotNull SentryAndroidOptions options) {
4244
this(options, AndroidCurrentDateProvider.getInstance());
4345
}

‎sentry-android-core/src/main/java/io/sentry/android/core/internal/util/AndroidCurrentDateProvider.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@
44
import io.sentry.transport.ICurrentDateProvider;
55
import org.jetbrains.annotations.ApiStatus;
66

7+
/**
8+
* An uptime clock: {@link SystemClock#uptimeMillis()} excludes time the device spent in deep sleep,
9+
* which neither the name nor the {@link ICurrentDateProvider} type says. {@link
10+
* io.sentry.transport.CurrentDateProvider} implements that same type with epoch milliseconds, so a
11+
* call site declaring the interface accepts either, and the two disagree by however long the device
12+
* has been suspended.
13+
*
14+
* <p>Superseded by {@link io.sentry.time.MonotonicTicker}, which counts deep sleep and says in its
15+
* name that only differences between its own ticks are meaningful. The annotation sits on {@link
16+
* #getInstance()}, the only way in, because a deprecated type warns on every import and an import
17+
* cannot carry a {@code @SuppressWarnings}.
18+
*/
719
@ApiStatus.Internal
820
public final class AndroidCurrentDateProvider implements ICurrentDateProvider {
921

1022
private static final ICurrentDateProvider instance = new AndroidCurrentDateProvider();
1123

24+
/**
25+
* @deprecated use {@link io.sentry.time.MonotonicTicker} to measure an interval.
26+
*/
27+
@Deprecated
1228
public static ICurrentDateProvider getInstance() {
1329
return instance;
1430
}

0 commit comments

Comments
 (0)