@@ -34,6 +34,12 @@ public final class Breadcrumb implements JsonUnknown, JsonSerializable {
3434 /** Dotted strings that indicate what the crumb is or where it comes from. */
3535 private @ Nullable String category ;
3636
37+ /**
38+ * Origin of the breadcrumb that is used to identify source of the breadcrumb. For example hybrid
39+ * SDKs can identify native breadcrumbs from JS or Flutter.
40+ */
41+ private @ Nullable String origin ;
42+
3743 /** The level of the event. */
3844 private @ Nullable SentryLevel level ;
3945
@@ -54,6 +60,7 @@ public Breadcrumb(final @NotNull Date timestamp) {
5460 this .message = breadcrumb .message ;
5561 this .type = breadcrumb .type ;
5662 this .category = breadcrumb .category ;
63+ this .origin = breadcrumb .origin ;
5764 final Map <String , Object > dataClone = CollectionUtils .newConcurrentHashMap (breadcrumb .data );
5865 if (dataClone != null ) {
5966 this .data = dataClone ;
@@ -78,6 +85,7 @@ public static Breadcrumb fromMap(
7885 String type = null ;
7986 @ NotNull Map <String , Object > data = new ConcurrentHashMap <>();
8087 String category = null ;
88+ String origin = null ;
8189 SentryLevel level = null ;
8290 Map <String , Object > unknown = null ;
8391
@@ -116,6 +124,9 @@ public static Breadcrumb fromMap(
116124 case JsonKeys .CATEGORY :
117125 category = (value instanceof String ) ? (String ) value : null ;
118126 break ;
127+ case JsonKeys .ORIGIN :
128+ origin = (value instanceof String ) ? (String ) value : null ;
129+ break ;
119130 case JsonKeys .LEVEL :
120131 String levelString = (value instanceof String ) ? (String ) value : null ;
121132 if (levelString != null ) {
@@ -140,6 +151,7 @@ public static Breadcrumb fromMap(
140151 breadcrumb .type = type ;
141152 breadcrumb .data = data ;
142153 breadcrumb .category = category ;
154+ breadcrumb .origin = origin ;
143155 breadcrumb .level = level ;
144156
145157 breadcrumb .setUnknown (unknown );
@@ -610,6 +622,24 @@ public void setCategory(@Nullable String category) {
610622 this .category = category ;
611623 }
612624
625+ /**
626+ * Returns the origin
627+ *
628+ * @return the origin
629+ */
630+ public @ Nullable String getOrigin () {
631+ return origin ;
632+ }
633+
634+ /**
635+ * Sets the origin
636+ *
637+ * @param origin the origin
638+ */
639+ public void setOrigin (@ Nullable String origin ) {
640+ this .origin = origin ;
641+ }
642+
613643 /**
614644 * Returns the SentryLevel
615645 *
@@ -638,12 +668,13 @@ public boolean equals(Object o) {
638668 && Objects .equals (message , that .message )
639669 && Objects .equals (type , that .type )
640670 && Objects .equals (category , that .category )
671+ && Objects .equals (origin , that .origin )
641672 && level == that .level ;
642673 }
643674
644675 @ Override
645676 public int hashCode () {
646- return Objects .hash (timestamp , message , type , category , level );
677+ return Objects .hash (timestamp , message , type , category , origin , level );
647678 }
648679
649680 // region json
@@ -665,6 +696,7 @@ public static final class JsonKeys {
665696 public static final String TYPE = "type" ;
666697 public static final String DATA = "data" ;
667698 public static final String CATEGORY = "category" ;
699+ public static final String ORIGIN = "origin" ;
668700 public static final String LEVEL = "level" ;
669701 }
670702
@@ -683,6 +715,9 @@ public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger
683715 if (category != null ) {
684716 writer .name (JsonKeys .CATEGORY ).value (category );
685717 }
718+ if (origin != null ) {
719+ writer .name (JsonKeys .ORIGIN ).value (origin );
720+ }
686721 if (level != null ) {
687722 writer .name (JsonKeys .LEVEL ).value (logger , level );
688723 }
@@ -707,6 +742,7 @@ public static final class Deserializer implements JsonDeserializer<Breadcrumb> {
707742 String type = null ;
708743 @ NotNull Map <String , Object > data = new ConcurrentHashMap <>();
709744 String category = null ;
745+ String origin = null ;
710746 SentryLevel level = null ;
711747
712748 Map <String , Object > unknown = null ;
@@ -736,6 +772,9 @@ public static final class Deserializer implements JsonDeserializer<Breadcrumb> {
736772 case JsonKeys .CATEGORY :
737773 category = reader .nextStringOrNull ();
738774 break ;
775+ case JsonKeys .ORIGIN :
776+ origin = reader .nextStringOrNull ();
777+ break ;
739778 case JsonKeys .LEVEL :
740779 try {
741780 level = new SentryLevel .Deserializer ().deserialize (reader , logger );
@@ -757,6 +796,7 @@ public static final class Deserializer implements JsonDeserializer<Breadcrumb> {
757796 breadcrumb .type = type ;
758797 breadcrumb .data = data ;
759798 breadcrumb .category = category ;
799+ breadcrumb .origin = origin ;
760800 breadcrumb .level = level ;
761801
762802 breadcrumb .setUnknown (unknown );
0 commit comments