Skip to content

Commit

Permalink
refactor: migrate native setup to install message
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed May 30, 2019
1 parent 85bbbe9 commit e0dae0e
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 59 deletions.
86 changes: 46 additions & 40 deletions ndk/src/main/java/com/bugsnag/android/ndk/NativeBridge.java
@@ -1,8 +1,5 @@
package com.bugsnag.android.ndk;

import com.bugsnag.android.Breadcrumb;
import com.bugsnag.android.NativeInterface;

import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
Expand Down Expand Up @@ -206,22 +203,8 @@ public static native void startedSession(String sessionID, String key,

public static native void updateUserName(String newValue);

private boolean loggingEnabled = true;
private final String reportDirectory;

/**
* Creates a new native bridge for interacting with native components.
* Configures logging and ensures that the reporting directory exists
* immediately.
*/
public NativeBridge() {
loggingEnabled = NativeInterface.getLoggingEnabled();
reportDirectory = NativeInterface.getNativeReportPath();
File outFile = new File(reportDirectory);
if (!outFile.exists() && !outFile.mkdirs()) {
warn("The native reporting directory cannot be created.");
}
}
private volatile boolean loggingEnabled = true;
private volatile String reportDirectory;

@Override
public void update(Observable observable, Object rawMessage) {
Expand Down Expand Up @@ -343,42 +326,65 @@ private void deliverPendingReports() {
}
}

/**
* Creates a new native bridge for interacting with native components.
* Configures logging and ensures that the reporting directory exists
* immediately.
*/
private void handleInstallMessage(Object arg) {
lock.lock();
try {
if (installed.get()) {
warn("Received duplicate setup message with arg: " + arg);
return;
}
String reportPath = reportDirectory + UUID.randomUUID().toString() + ".crash";
install(reportPath, true, Build.VERSION.SDK_INT, is32bit());
installed.set(true);
} finally {
lock.unlock();
}
}

private boolean is32bit() {
String[] abis = NativeInterface.getCpuAbi();
boolean is32bit;

boolean is32bit = true;
for (String abi : abis) {
if (abi.contains("64")) {
is32bit = false;
break;
if (arg instanceof List) {
@SuppressWarnings("unchecked")
List<Object> values = (List<Object>) arg;
if (values.size() == 4
&& values.get(1) instanceof Boolean
&& values.get(2) instanceof Boolean
&& values.get(3) instanceof String) {

is32bit = loggingEnabled = (boolean) values.get(1);
loggingEnabled = (boolean) values.get(2);
reportDirectory = (String) values.get(3);

File outFile = new File(reportDirectory);
if (!outFile.exists() && !outFile.mkdirs()) {
warn("The native reporting directory cannot be created.");
}

String reportPath = reportDirectory + UUID.randomUUID().toString() + ".crash";
install(reportPath, true, Build.VERSION.SDK_INT, is32bit);
installed.set(true);
} else {
warn("Received malformed NDK install message.");
}
} else {
warn("Received malformed NDK install message.");
}

} finally {
lock.unlock();
}
return is32bit;
}

private void handleAddBreadcrumb(Object arg) {
if (arg instanceof Breadcrumb) {
Breadcrumb crumb = (Breadcrumb) arg;
addBreadcrumb(crumb.getName(), crumb.getType().toString(),
crumb.getTimestamp(), crumb.getMetadata());
} else {
warn("Attempted to add non-breadcrumb: " + arg);
if (arg instanceof List) {
@SuppressWarnings("unchecked")
List<Object> values = (List<Object>) arg;

if (values.size() == 4) {
addBreadcrumb((String) values.get(0), (String) values.get(1),
(String) values.get(2), values.get(3));
return;
}
}
warn("Attempted to add non-breadcrumb: " + arg);
}

private void handleAddMetadata(Object arg) {
Expand Down
Expand Up @@ -19,6 +19,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

Expand Down Expand Up @@ -255,23 +256,27 @@ public void testClientClearUserSendsMessage() {
@Test
public void testLeaveStringBreadcrumbSendsMessage() {
client.leaveBreadcrumb("Drift 4 units left");
Breadcrumb crumb = (Breadcrumb)findMessageInQueue(
NativeBridge.MessageType.ADD_BREADCRUMB, Breadcrumb.class);
assertEquals(BreadcrumbType.MANUAL, crumb.getType());
assertEquals("manual", crumb.getName());
assertEquals(1, crumb.getMetadata().size());
assertEquals("Drift 4 units left", crumb.getMetadata().get("message"));
List<Object> crumb = (List)findMessageInQueue(
NativeBridge.MessageType.ADD_BREADCRUMB, List.class);
assertEquals("manual", crumb.get(0));
assertEquals(BreadcrumbType.MANUAL.toString(), crumb.get(1));

Map<String, Object> metaData = ((Map)crumb.get(3));
assertEquals(1, metaData.size());
assertEquals("Drift 4 units left", metaData.get("message"));
}

@Test
public void testLeaveStringBreadcrumbDirectlySendsMessage() {
client.breadcrumbs.add(new Breadcrumb("Drift 4 units left"));
Breadcrumb crumb = (Breadcrumb)findMessageInQueue(
NativeBridge.MessageType.ADD_BREADCRUMB, Breadcrumb.class);
assertEquals(BreadcrumbType.MANUAL, crumb.getType());
assertEquals("manual", crumb.getName());
assertEquals(1, crumb.getMetadata().size());
assertEquals("Drift 4 units left", crumb.getMetadata().get("message"));
List<Object> crumb = (List)findMessageInQueue(
NativeBridge.MessageType.ADD_BREADCRUMB, List.class);
assertEquals("manual", crumb.get(0));
assertEquals(BreadcrumbType.MANUAL.toString(), crumb.get(1));

Map<String, Object> metaData = ((Map)crumb.get(3));
assertEquals(1, metaData.size());
assertEquals("Drift 4 units left", metaData.get("message"));
}

@Test
Expand All @@ -289,11 +294,12 @@ public void testClearBreadcrumbsDirectlySendsMessage() {
@Test
public void testLeaveBreadcrumbSendsMessage() {
client.leaveBreadcrumb("Rollback", BreadcrumbType.LOG, new HashMap<String, String>());
Breadcrumb crumb = (Breadcrumb)findMessageInQueue(
NativeBridge.MessageType.ADD_BREADCRUMB, Breadcrumb.class);
assertEquals(BreadcrumbType.LOG, crumb.getType());
assertEquals("Rollback", crumb.getName());
assertEquals(0, crumb.getMetadata().size());
List<Object> crumb = (List)findMessageInQueue(
NativeBridge.MessageType.ADD_BREADCRUMB, List.class);

assertEquals("Rollback", crumb.get(0));
assertEquals(BreadcrumbType.LOG.toString(), crumb.get(1));
assertEquals(0, ((Map)crumb.get(3)).size());
}

private Object findMessageInQueue(NativeBridge.MessageType type, Class<?> argClass) {
Expand Down
12 changes: 11 additions & 1 deletion sdk/src/main/java/com/bugsnag/android/Breadcrumbs.java
Expand Up @@ -5,6 +5,8 @@
import android.support.annotation.NonNull;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Observable;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
Expand Down Expand Up @@ -53,8 +55,16 @@ private void addToStore(@NonNull Breadcrumb breadcrumb) {
store.add(breadcrumb);
pruneBreadcrumbs();
setChanged();

List<Object> breadcrumbValues = Arrays.asList(
breadcrumb.getName(),
breadcrumb.getType().toString(),
breadcrumb.getTimestamp(),
breadcrumb.getMetadata()
);

notifyObservers(new NativeBridge.Message(
NativeBridge.MessageType.ADD_BREADCRUMB, breadcrumb));
NativeBridge.MessageType.ADD_BREADCRUMB, breadcrumbValues));
} catch (IOException ex) {
Logger.warn("Dropping breadcrumb because it could not be serialized", ex);
}
Expand Down
11 changes: 10 additions & 1 deletion sdk/src/main/java/com/bugsnag/android/Client.java
Expand Up @@ -24,8 +24,10 @@
import android.view.OrientationEventListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;
Expand Down Expand Up @@ -284,7 +286,14 @@ public void onReceive(Context context, Intent intent) {

void sendNativeSetupNotification() {
setChanged();
super.notifyObservers(new NativeBridge.Message(NativeBridge.MessageType.INSTALL, config));
List<Object> obj = Arrays.asList(
config,
NativeInterface.is32bit(),
NativeInterface.getLoggingEnabled(),
NativeInterface.getNativeReportPath()
);

super.notifyObservers(new NativeBridge.Message(NativeBridge.MessageType.INSTALL, obj));
try {
Async.run(new Runnable() {
@Override
Expand Down
13 changes: 13 additions & 0 deletions sdk/src/main/java/com/bugsnag/android/NativeInterface.java
Expand Up @@ -339,4 +339,17 @@ public void beforeNotify(@NonNull Report report) {
}
});
}

static boolean is32bit() {
String[] abis = NativeInterface.getCpuAbi();

boolean is32bit = true;
for (String abi : abis) {
if (abi.contains("64")) {
is32bit = false;
break;
}
}
return is32bit;
}
}

0 comments on commit e0dae0e

Please sign in to comment.