Skip to content

Commit

Permalink
fix(thread state): added nullability annotation to `Thread.State.getD…
Browse files Browse the repository at this point in the history
…escriptor`
  • Loading branch information
lemnik committed Sep 24, 2021
1 parent 0065ec3 commit c73f990
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 20 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## TBD

* Capture and report Thread.state for Android Runtime threads
[#1367](https://github.com/bugsnag/bugsnag-android/pull/1367)

## 5.13.0 (2021-09-22)

* Capture breadcrumbs for OkHttp network requests
Expand Down
49 changes: 31 additions & 18 deletions bugsnag-android-core/src/main/java/com/bugsnag/android/Thread.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,24 @@ public void toStream(@NonNull JsonStream stream) throws IOException {
* a state could not be captured or mapped.
*/
public enum State {
NEW,
BLOCKED,
RUNNABLE,
TERMINATED,
TIMED_WAITING,
WAITING,
UNKNOWN;
NEW("NEW"),
BLOCKED("BLOCKED"),
RUNNABLE("RUNNABLE"),
TERMINATED("TERMINATED"),
TIMED_WAITING("TIMED_WAITING"),
WAITING("WAITING"),
UNKNOWN("UNKNOWN");

private final String descriptor;

State(String descriptor) {
this.descriptor = descriptor;
}

@NonNull
public String getDescriptor() {
return descriptor;
}

@NonNull
public static State forThread(@NonNull java.lang.Thread thread) {
Expand All @@ -154,24 +165,26 @@ public static State forThread(@NonNull java.lang.Thread thread) {
}

/**
* An exception-safe wrapper for {@link #valueOf(String)} which also handles {@code null}
* names. This method is used in-preference to the standard {@code valueOf} as it will
* return {@link #UNKNOWN} instead of throwing an exception.
* Lookup the {@code State} for a given {@link #getDescriptor() descriptor} code. Unlike
* {@link #valueOf(String) valueOf}, this method will return {@link #UNKNOWN} is no
* matching {@code State} constant can be found.
*
* @param name the name of the state constant to lookup
* @return the named {@link State} or {@link #UNKNOWN}
* @param descriptor a consistent descriptor of the state constant to lookup
* @return the requested {@link State} or {@link #UNKNOWN}
*/
@NonNull
public static State byName(@Nullable String name) {
if (name == null) {
public static State byDescriptor(@Nullable String descriptor) {
if (descriptor == null) {
return UNKNOWN;
}

try {
return valueOf(name);
} catch (IllegalArgumentException iae) {
return UNKNOWN;
for (State state : values()) {
if (state.getDescriptor().equals(descriptor)) {
return state;
}
}

return UNKNOWN;
}

@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ThreadInternal internal constructor(
writer.name("id").value(id)
writer.name("name").value(name)
writer.name("type").value(type.desc)
writer.name("state").value(state.name)
writer.name("state").value(state.descriptor)

writer.name("stacktrace")
writer.beginArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Thread deserialize(Map<String, Object> map) {
MapUtils.<String>getOrThrow(map, "name"),
ThreadType.valueOf(type.toUpperCase(Locale.US)),
errorReportingThread,
Thread.State.byName(MapUtils.<String>getOrThrow(map, "state")),
Thread.State.byDescriptor(MapUtils.<String>getOrThrow(map, "state")),
new Stacktrace(frames),
logger
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ internal class ThreadSerializer : MapSerializer<Thread> {
map["name"] = thread.name
map["type"] = thread.type.toString().toLowerCase(Locale.US)
map["errorReportingThread"] = thread.errorReportingThread
map["state"] = thread.state.descriptor

map["stacktrace"] = thread.stacktrace.map {
val frame = mutableMapOf<String, Any?>()
Expand Down

0 comments on commit c73f990

Please sign in to comment.