Skip to content

Commit

Permalink
v4.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench authored Jan 7, 2019
2 parents c5341f8 + d51b8ec commit 9f69368
Show file tree
Hide file tree
Showing 55 changed files with 496 additions and 200 deletions.
20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
# Changelog

## 4.X.X (TBD)
## 4.10.0 (2019-01-07)

* Improve kotlin support by allowing property access
[#393](https://github.com/bugsnag/bugsnag-android/pull/393)

* Added additional nullability annotations to public API
[#395](https://github.com/bugsnag/bugsnag-android/pull/395)

* Migrate metaData.device.cpuAbi to device.cpuAbi in JSON payload
[#404](https://github.com/bugsnag/bugsnag-android/pull/404)

### Bug fixes

* Make config.metadata publicly accessible
[#406](https://github.com/bugsnag/bugsnag-android/pull/406)
* Add binary architecture of application to payload
[#389](https://github.com/bugsnag/bugsnag-android/pull/389)

* Prevent errors from leaving a self-referencing breadcrumb
[#391](https://github.com/bugsnag/bugsnag-android/pull/391)

* Fix calculation of durationInForeground when autoCaptureSessions is false
[#394](https://github.com/bugsnag/bugsnag-android/pull/394)

* Prevent Bugsnag.init from instantiating more than one client
[#403](https://github.com/bugsnag/bugsnag-android/pull/403)

* Make config.metadata publicly accessible
[#406](https://github.com/bugsnag/bugsnag-android/pull/406)

## 4.9.3 (2018-11-29)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Build status](https://travis-ci.org/bugsnag/bugsnag-android.svg?branch=master)](https://travis-ci.org/bugsnag/bugsnag-android)
[![Coverage Status](https://coveralls.io/repos/github/bugsnag/bugsnag-android/badge.svg?branch=master)](https://coveralls.io/github/bugsnag/bugsnag-android?branch=master)
<!-- Auto-generated line below: -->
![Method count and size](https://img.shields.io/badge/Methods%20and%20size-88%20classes%20|%20666%20methods%20|%20348%20fields%20|%20128%20KB-e91e63.svg)
![Method count and size](https://img.shields.io/badge/Methods%20and%20size-88%20classes%20|%20678%20methods%20|%20350%20fields%20|%20132%20KB-e91e63.svg)

Get comprehensive [Android crash reports](https://www.bugsnag.com/platforms/android/) to quickly debug errors.

Expand Down
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ buildscript {
mavenCentral()
jcenter()
}
ext.kotlin_version = '1.2.30'
ext.kotlin_version = '1.3.10'
ext.agpVersion = "3.2.1"

dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath "com.android.tools.build:gradle:$agpVersion"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.2'
Expand Down
6 changes: 3 additions & 3 deletions examples/sdk-app-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "com.android.tools.build:gradle:$agpVersion"
classpath 'com.bugsnag:bugsnag-android-gradle-plugin:3.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.30"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

Expand Down Expand Up @@ -80,7 +80,7 @@ dependencies {
// api project(path: ':ndk', configuration: 'default')
implementation 'com.android.support:appcompat-v7:27.0.0'
implementation 'com.android.support:support-v4:27.0.0'
kotlinExampleImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.30"
kotlinExampleImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
androidTestImplementation "com.android.support.test:runner:0.5", {
exclude group: 'com.android.support', module: 'support-annotations'
}
Expand Down
4 changes: 2 additions & 2 deletions features/fixtures/mazerunner/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ buildscript {
mavenCentral()
jcenter()
}
ext.kotlin_version = '1.2.30'
ext.kotlin_version = '1.3.10'

dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
Expand Down Expand Up @@ -68,7 +68,7 @@ android {
dependencies {
implementation(name:'bugsnag-android', ext:'aar')
implementation(name:'bugsnag-android-ndk', ext:'aar')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.21"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.facebook.infer.annotation:infer-annotation:0.11.2"
api "com.android.support:support-annotations:27.0.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ internal fun createSlowDelivery(context: Context): Delivery {
val delivery = DefaultDelivery(cm)

return object : Delivery {
override fun deliver(payload: SessionTrackingPayload?, config: Configuration?) {
override fun deliver(payload: SessionTrackingPayload, config: Configuration) {
Thread.sleep(500)
delivery.deliver(payload, config)
}

override fun deliver(report: Report?, config: Configuration?) {
override fun deliver(report: Report, config: Configuration) {
Thread.sleep(500)
delivery.deliver(report, config)
}
Expand All @@ -47,18 +47,18 @@ internal fun createCustomHeaderDelivery(context: Context): Delivery {
return object : Delivery {
val delivery: DefaultDelivery = createDefaultDelivery(context)

override fun deliver(payload: SessionTrackingPayload?, config: Configuration?) {
deliver(config?.sessionEndpoint, payload, config?.sessionApiHeaders)
override fun deliver(payload: SessionTrackingPayload, config: Configuration) {
deliver(config.sessionEndpoint, payload, config.sessionApiHeaders)
}

override fun deliver(report: Report?, config: Configuration?) {
deliver(config?.endpoint, report, config?.errorApiHeaders)
override fun deliver(report: Report, config: Configuration) {
deliver(config.endpoint, report, config.errorApiHeaders)
}

fun deliver(endpoint: String?,
streamable: JsonStream.Streamable?,
headers: MutableMap<String, String>?) {
headers!!["Custom-Client"] = "Hello World"
fun deliver(endpoint: String,
streamable: JsonStream.Streamable,
headers: MutableMap<String, String>) {
headers["Custom-Client"] = "Hello World"
delivery.deliver(endpoint, streamable, headers)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ abstract internal class Scenario(protected val config: Configuration,
protected fun disableSessionDelivery() {
val baseDelivery = Bugsnag.getClient().config.delivery
Bugsnag.getClient().config.delivery = object: Delivery {
override fun deliver(payload: SessionTrackingPayload?, config: Configuration?) {
override fun deliver(payload: SessionTrackingPayload, config: Configuration) {
throw DeliveryFailureException("Session Delivery NOP", RuntimeException("NOP"))
}

override fun deliver(report: Report?, config: Configuration?) {
override fun deliver(report: Report, config: Configuration) {
baseDelivery.deliver(report, config)
}
}
Expand All @@ -34,11 +34,11 @@ abstract internal class Scenario(protected val config: Configuration,
protected fun disableReportDelivery() {
val baseDelivery = Bugsnag.getClient().config.delivery
Bugsnag.getClient().config.delivery = object: Delivery {
override fun deliver(payload: SessionTrackingPayload?, config: Configuration?) {
override fun deliver(payload: SessionTrackingPayload, config: Configuration) {
baseDelivery.deliver(payload, config)
}

override fun deliver(report: Report?, config: Configuration?) {
override fun deliver(report: Report, config: Configuration) {
throw DeliveryFailureException("Session Delivery NOP", RuntimeException("NOP"))
}
}
Expand All @@ -57,11 +57,11 @@ abstract internal class Scenario(protected val config: Configuration,

protected fun disableAllDelivery(config: Configuration) {
config.delivery = object: Delivery {
override fun deliver(payload: SessionTrackingPayload?, config: Configuration?) {
override fun deliver(payload: SessionTrackingPayload, config: Configuration) {
throw DeliveryFailureException("Error Delivery NOP", RuntimeException("NOP"))
}

override fun deliver(report: Report?, config: Configuration?) {
override fun deliver(report: Report, config: Configuration) {
throw DeliveryFailureException("Session Delivery NOP", RuntimeException("NOP"))
}
}
Expand Down
1 change: 1 addition & 0 deletions features/handled_exception.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Scenario: Test handled Kotlin Exception
And the payload field "events" is an array with 1 element
And the exception "errorClass" equals "java.lang.RuntimeException"
And the exception "message" equals "HandledExceptionScenario"
And the payload field "events.0.device.cpuAbi" is a non-empty array for request 0

Scenario: Test handled Java Exception
When I run "HandledExceptionJavaScenario"
Expand Down
2 changes: 2 additions & 0 deletions features/native_api.feature
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Feature: Native API
And the event "user.id" equals "324523"
And the event "user.email" is null
And the event "unhandled" is false
And the event "app.binaryArch" is not null
And the payload field "events.0.device.cpuAbi" is a non-empty array for request 0

Scenario: Adding user information in Java followed by a C crash
When I run "CXXJavaUserInfoNativeCrashScenario"
Expand Down
2 changes: 2 additions & 0 deletions features/native_crash_handling.feature
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Feature: Native crash reporting
And the exception "type" equals "c"
And the event "severity" equals "error"
And the event "unhandled" is true
And the event "app.binaryArch" is not null
And the payload field "events.0.device.cpuAbi" is a non-empty array for request 0

# This scenario will not pass on API levels < 18, as stack corruption
# is handled without calling atexit handlers, etc.
Expand Down
2 changes: 1 addition & 1 deletion features/steps/build_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
And the payload field "events.0.metaData.device.time" is not null for request #{index}
And the payload field "events.0.severity" is not null for request #{index}
And the payload field "events.0.severityReason.type" is not null for request #{index}
And the payload field "events.0.metaData.device.cpuAbi" is a non-empty array for request #{index}
And the payload field "events.0.device.cpuAbi" is a non-empty array for request #{index}
}
end

Expand Down
1 change: 1 addition & 0 deletions features/unhandled_exception.feature
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Scenario: Test Unhandled Kotlin Exception without Session
And the exception "errorClass" equals "java.lang.RuntimeException"
And the exception "message" equals "UnhandledExceptionScenario"
And the event "session" is null
And the payload field "events.0.device.cpuAbi" is a non-empty array for request 0

Scenario: Test Unhandled Java Exception with Session
When I run "UnhandledExceptionJavaScenario"
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ org.gradle.jvmargs=-Xmx1536m
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
VERSION_NAME=4.9.3
VERSION_NAME=4.10.0
GROUP=com.bugsnag
POM_SCM_URL=https://github.com/bugsnag/bugsnag-android
POM_SCM_CONNECTION=scm:[email protected]:bugsnag/bugsnag-android.git
Expand Down
18 changes: 18 additions & 0 deletions ndk/src/main/jni/bugsnag.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
#include "bugsnag_ndk.h"
#include "report.h"
#include "utils/stack_unwinder.h"
#include "metadata.h"
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static JNIEnv *bsg_global_jni_env = NULL;

void bugsnag_set_binary_arch(JNIEnv *env);

void bugsnag_init(JNIEnv *env) { bsg_global_jni_env = env; }

void bugsnag_notify_env(JNIEnv *env, char *name, char *message,
Expand Down Expand Up @@ -109,6 +112,9 @@ void bugsnag_notify_env(JNIEnv *env, char *name, char *message,
jstring jname = (*env)->NewStringUTF(env, name);
jstring jmessage = (*env)->NewStringUTF(env, message);

// set application's binary arch
bugsnag_set_binary_arch(env);

(*env)->CallStaticVoidMethod(env, interface_class, notify_method, jname,
jmessage, jseverity, trace);

Expand All @@ -119,6 +125,18 @@ void bugsnag_notify_env(JNIEnv *env, char *name, char *message,
(*env)->DeleteLocalRef(env, interface_class);
}

void bugsnag_set_binary_arch(JNIEnv *env) {
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
jmethodID set_arch_method = (*env)->GetStaticMethodID(
env, interface_class, "setBinaryArch", "(Ljava/lang/String;)V");

jstring arch = (*env)->NewStringUTF(env, bsg_binary_arch());
(*env)->CallStaticVoidMethod(env, interface_class, set_arch_method, arch);
(*env)->DeleteLocalRef(env, arch);
(*env)->DeleteLocalRef(env, interface_class);
}

void bugsnag_set_user_env(JNIEnv *env, char *id, char *email, char *name) {
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
Expand Down
17 changes: 17 additions & 0 deletions ndk/src/main/jni/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,20 @@ void bsg_populate_crumb_metadata(JNIEnv *env, bugsnag_breadcrumb *crumb,
(*env)->DeleteLocalRef(env, keylist);
}

char *bsg_binary_arch() {
#if defined(__i386__)
return "x86";
#elif defined(__x86_64__)
return "x86_64";
#elif defined(__arm__)
return "arm32";
#elif defined(__aarch64__)
return "arm64";
#else
return "unknown";
#endif
}

void bsg_populate_app_data(JNIEnv *env, bsg_jni_cache *jni_cache,
bugsnag_report *report) {
jobject data = (*env)->CallStaticObjectMethod(
Expand Down Expand Up @@ -232,6 +246,9 @@ void bsg_populate_app_data(JNIEnv *env, bsg_jni_cache *jni_cache,
report->app.in_foreground =
bsg_get_map_value_bool(env, jni_cache, data, "inForeground");

bsg_strncpy_safe(report->app.binaryArch,
bsg_binary_arch(),
sizeof(report->app.binaryArch));
(*env)->DeleteLocalRef(env, data);
}

Expand Down
3 changes: 3 additions & 0 deletions ndk/src/main/jni/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ void bsg_populate_metadata(JNIEnv *env, bugsnag_report *report, jobject metadata
*/
void bsg_populate_crumb_metadata(JNIEnv *env, bugsnag_breadcrumb *crumb,
jobject metadata);

char *bsg_binary_arch();

#endif
1 change: 1 addition & 0 deletions ndk/src/main/jni/report.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ typedef struct {
bool in_foreground;
bool low_memory;
size_t memory_usage;
char binaryArch[32];
} bsg_app_info;

typedef struct {
Expand Down
16 changes: 10 additions & 6 deletions ndk/src/main/jni/utils/serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ char *bsg_serialize_report_to_json_string(bugsnag_report *report) {
if (strlen(report->app.build_uuid) > 0) {
json_object_dotset_string(event, "app.buildUUID", report->app.build_uuid);
}
json_object_dotset_string(event, "app.binaryArch",
report->app.binaryArch);
json_object_dotset_number(event, "app.duration", report->app.duration);
json_object_dotset_number(event, "app.durationInForeground",
report->app.duration_in_foreground);
Expand All @@ -182,6 +184,14 @@ char *bsg_serialize_report_to_json_string(bugsnag_report *report) {
json_object_dotset_string(event, "device.model", report->device.model);
json_object_dotset_string(event, "device.orientation",
report->device.orientation);

JSON_Value *abi_val = json_value_init_array();
JSON_Array *cpu_abis = json_value_get_array(abi_val);
json_object_dotset_value(event, "device.cpuAbi", abi_val);
for (int i = 0; i < report->device.cpu_abi_count; i++) {
json_array_append_string(cpu_abis, report->device.cpu_abi[i].value);
}

json_object_dotset_string(event, "metaData.device.osBuild",
report->device.os_build);
json_object_dotset_number(event, "device.totalMemory",
Expand Down Expand Up @@ -212,12 +222,6 @@ char *bsg_serialize_report_to_json_string(bugsnag_report *report) {
gmtime(&report->device.time));
json_object_dotset_string(event, "metaData.device.time", report_time);
}
JSON_Value *abi_val = json_value_init_array();
JSON_Array *cpu_abis = json_value_get_array(abi_val);
json_object_dotset_value(event, "metaData.device.cpuAbi", abi_val);
for (int i = 0; i < report->device.cpu_abi_count; i++) {
json_array_append_string(cpu_abis, report->device.cpu_abi[i].value);
}

// Serialize custom metadata
{
Expand Down
3 changes: 2 additions & 1 deletion sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ android {
abortOnError true
warningsAsErrors true
checkAllWarnings true
baseline file("lint-baseline.xml")
}

// TODO replace with https://issuetracker.google.com/issues/72050365 once released.
Expand All @@ -51,7 +52,7 @@ coveralls {
dependencies {
api "com.android.support:support-annotations:$supportLibVersion"

androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

testImplementation "junit:junit:$junitVersion"
testImplementation "org.mockito:mockito-core:$mockitoVersion"
Expand Down
4 changes: 4 additions & 0 deletions sdk/lint-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="4" by="lint 3.2.1" client="gradle" variant="all" version="3.2.1">

</issues>
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void testSetReleaseStage() throws Exception {
@Test
public void testSetAutoCaptureSessions() throws Exception {
client.setAutoCaptureSessions(true);
assertEquals(true, config.shouldAutoCaptureSessions());
assertEquals(true, config.getAutoCaptureSessions());
}

@Test
Expand Down
Loading

0 comments on commit 9f69368

Please sign in to comment.