Skip to content

Commit

Permalink
Replace Calendar.getInstance with System.currentTimeMillis for breadc…
Browse files Browse the repository at this point in the history
…rumb ctor (#3736)
  • Loading branch information
romtsn authored Oct 3, 2024
1 parent 7e57220 commit b5b093e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- For example, (this is already a default behavior) to redact all `TextView`s and their subclasses (`RadioButton`, `EditText`, etc.): `options.experimental.sessionReplay.addRedactViewClass("android.widget.TextView")`
- If you're using code obfuscation, adjust your proguard-rules accordingly, so your custom view class name is not minified
- Fix ensure Application Context is used even when SDK is initialized via Activity Context ([#3669](https://github.com/getsentry/sentry-java/pull/3669))
- Fix potential ANRs due to `Calendar.getInstance` usage in Breadcrumbs constructor ([#3736](https://github.com/getsentry/sentry-java/pull/3736))

*Breaking changes*:

Expand Down
1 change: 1 addition & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public final class io/sentry/BaggageHeader {

public final class io/sentry/Breadcrumb : io/sentry/JsonSerializable, io/sentry/JsonUnknown {
public fun <init> ()V
public fun <init> (J)V
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/util/Date;)V
public static fun debug (Ljava/lang/String;)Lio/sentry/Breadcrumb;
Expand Down
34 changes: 26 additions & 8 deletions sentry/src/main/java/io/sentry/Breadcrumb.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
/** Series of application events */
public final class Breadcrumb implements JsonUnknown, JsonSerializable {

/** A timestamp representing when the breadcrumb occurred. */
private final @NotNull Date timestamp;
/** A timestamp representing when the breadcrumb occurred in milliseconds. */
private @Nullable final Long timestampMs;

/** A timestamp representing when the breadcrumb occurred as java.util.Date. */
private @Nullable Date timestamp;

/** If a message is provided, its rendered as text and the whitespace is preserved. */
private @Nullable String message;
Expand Down Expand Up @@ -51,12 +54,20 @@ public final class Breadcrumb implements JsonUnknown, JsonSerializable {
*
* @param timestamp the timestamp
*/
@SuppressWarnings("JavaUtilDate")
public Breadcrumb(final @NotNull Date timestamp) {
this.timestamp = timestamp;
this.timestampMs = null;
}

public Breadcrumb(final long timestamp) {
this.timestampMs = timestamp;
this.timestamp = null;
}

Breadcrumb(final @NotNull Breadcrumb breadcrumb) {
this.timestamp = breadcrumb.timestamp;
this.timestampMs = breadcrumb.timestampMs;
this.message = breadcrumb.message;
this.type = breadcrumb.type;
this.category = breadcrumb.category;
Expand Down Expand Up @@ -504,7 +515,7 @@ public static Breadcrumb fromMap(

/** Breadcrumb ctor */
public Breadcrumb() {
this(DateUtils.getCurrentDateTime());
this(System.currentTimeMillis());
}

/**
Expand All @@ -518,13 +529,20 @@ public Breadcrumb(@Nullable String message) {
}

/**
* Returns the Breadcrumb's timestamp
* Returns the Breadcrumb's timestamp as java.util.Date
*
* @return the timestamp
*/
@SuppressWarnings({"JdkObsolete", "JavaUtilDate"})
@SuppressWarnings("JavaUtilDate")
public @NotNull Date getTimestamp() {
return (Date) timestamp.clone();
if (timestamp != null) {
return (Date) timestamp.clone();
} else if (timestampMs != null) {
// we memoize it here into timestamp to avoid instantiating Calendar again and again
timestamp = DateUtils.getDateTime(timestampMs);
return timestamp;
}
throw new IllegalStateException("No timestamp set for breadcrumb");
}

/**
Expand Down Expand Up @@ -664,7 +682,7 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Breadcrumb that = (Breadcrumb) o;
return timestamp.getTime() == that.timestamp.getTime()
return getTimestamp().getTime() == that.getTimestamp().getTime()
&& Objects.equals(message, that.message)
&& Objects.equals(type, that.type)
&& Objects.equals(category, that.category)
Expand Down Expand Up @@ -704,7 +722,7 @@ public static final class JsonKeys {
public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger logger)
throws IOException {
writer.beginObject();
writer.name(JsonKeys.TIMESTAMP).value(logger, timestamp);
writer.name(JsonKeys.TIMESTAMP).value(logger, getTimestamp());
if (message != null) {
writer.name(JsonKeys.MESSAGE).value(message);
}
Expand Down
7 changes: 7 additions & 0 deletions sentry/src/test/java/io/sentry/BreadcrumbTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.sentry

import java.util.Date
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
Expand Down Expand Up @@ -100,6 +101,12 @@ class BreadcrumbTest {
assertNotNull(breadcrumb.timestamp)
}

@Test
fun `breadcrumb can be created with Date timestamp`() {
val breadcrumb = Breadcrumb(Date(123L))
assertEquals(123L, breadcrumb.timestamp.time)
}

@Test
fun `breadcrumb takes message on ctor`() {
val breadcrumb = Breadcrumb("this is a test")
Expand Down

0 comments on commit b5b093e

Please sign in to comment.