Skip to content

Commit

Permalink
Updated Bugsnag to v5.30.0
Browse files Browse the repository at this point in the history
  • Loading branch information
M66B committed Jun 28, 2023
1 parent 03de3b5 commit 21c71ff
Show file tree
Hide file tree
Showing 19 changed files with 109 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,56 @@ package com.bugsnag.android
import android.app.Activity
import android.app.Application
import android.os.Bundle
import java.util.WeakHashMap

internal class ActivityBreadcrumbCollector(
private val cb: (message: String, method: Map<String, Any>) -> Unit
) : Application.ActivityLifecycleCallbacks {

var prevState: String? = null
private val prevState = WeakHashMap<Activity, String>()

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) =
leaveBreadcrumb(getActivityName(activity), "onCreate()", savedInstanceState != null)
leaveBreadcrumb(activity, "onCreate()", savedInstanceState != null)

override fun onActivityStarted(activity: Activity) =
leaveBreadcrumb(getActivityName(activity), "onStart()")
leaveBreadcrumb(activity, "onStart()")

override fun onActivityResumed(activity: Activity) =
leaveBreadcrumb(getActivityName(activity), "onResume()")
leaveBreadcrumb(activity, "onResume()")

override fun onActivityPaused(activity: Activity) =
leaveBreadcrumb(getActivityName(activity), "onPause()")
leaveBreadcrumb(activity, "onPause()")

override fun onActivityStopped(activity: Activity) =
leaveBreadcrumb(getActivityName(activity), "onStop()")
leaveBreadcrumb(activity, "onStop()")

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) =
leaveBreadcrumb(getActivityName(activity), "onSaveInstanceState()")
leaveBreadcrumb(activity, "onSaveInstanceState()")

override fun onActivityDestroyed(activity: Activity) =
leaveBreadcrumb(getActivityName(activity), "onDestroy()")
override fun onActivityDestroyed(activity: Activity) {
leaveBreadcrumb(activity, "onDestroy()")
prevState.remove(activity)
}

private fun getActivityName(activity: Activity) = activity.javaClass.simpleName

private fun leaveBreadcrumb(activityName: String, lifecycleCallback: String, hasBundle: Boolean? = null) {
private fun leaveBreadcrumb(
activity: Activity,
lifecycleCallback: String,
hasBundle: Boolean? = null
) {
val metadata = mutableMapOf<String, Any>()
if (hasBundle != null) {
metadata["hasBundle"] = hasBundle
}
val previousVal = prevState
val previousVal = prevState[activity]

if (previousVal != null) {
metadata["previous"] = previousVal
}

val activityName = getActivityName(activity)
cb("$activityName#$lifecycleCallback", metadata)
prevState = lifecycleCallback
prevState[activity] = lifecycleCallback
}
}
4 changes: 3 additions & 1 deletion app/src/main/java/com/bugsnag/android/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import static com.bugsnag.android.SeverityReason.REASON_HANDLED_EXCEPTION;

import com.bugsnag.android.internal.BackgroundTaskService;
import com.bugsnag.android.internal.ImmutableConfig;
import com.bugsnag.android.internal.InternalMetrics;
import com.bugsnag.android.internal.InternalMetricsImpl;
import com.bugsnag.android.internal.InternalMetricsNoop;
import com.bugsnag.android.internal.StateObserver;
import com.bugsnag.android.internal.TaskType;
import com.bugsnag.android.internal.dag.ConfigModule;
import com.bugsnag.android.internal.dag.ContextModule;
import com.bugsnag.android.internal.dag.SystemServiceModule;
Expand Down Expand Up @@ -303,7 +305,7 @@ private void start() {
registerListenersInBackground();

// Leave auto breadcrumb
Map<String, Object> data = Collections.emptyMap();
Map<String, Object> data = new HashMap<>();
leaveAutoBreadcrumb("Bugsnag loaded", BreadcrumbType.STATE, data);

logger.d("Bugsnag loaded");
Expand Down
19 changes: 10 additions & 9 deletions app/src/main/java/com/bugsnag/android/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
Expand Down Expand Up @@ -305,7 +306,7 @@ public long getLaunchDurationMillis() {
* By default, this value is set at 5,000ms. Setting the value to 0 will count all crashes
* as launch crashes until markLaunchCompleted() is called.
*/
public void setLaunchDurationMillis(long launchDurationMillis) {
public void setLaunchDurationMillis(@IntRange(from = 0) long launchDurationMillis) {
if (launchDurationMillis >= MIN_LAUNCH_CRASH_THRESHOLD_MS) {
impl.setLaunchDurationMillis(launchDurationMillis);
} else {
Expand Down Expand Up @@ -524,12 +525,12 @@ public int getMaxBreadcrumbs() {
*
* By default, 100 breadcrumbs are stored: this can be amended up to a maximum of 500.
*/
public void setMaxBreadcrumbs(int maxBreadcrumbs) {
public void setMaxBreadcrumbs(@IntRange(from = 0, to = 500) int maxBreadcrumbs) {
if (maxBreadcrumbs >= MIN_BREADCRUMBS && maxBreadcrumbs <= MAX_BREADCRUMBS) {
impl.setMaxBreadcrumbs(maxBreadcrumbs);
} else {
getLogger().e("Invalid configuration value detected. "
+ "Option maxBreadcrumbs should be an integer between 0-100. "
+ "Option maxBreadcrumbs should be an integer between 0-500. "
+ "Supplied value is " + maxBreadcrumbs);
}
}
Expand All @@ -540,8 +541,8 @@ public void setMaxBreadcrumbs(int maxBreadcrumbs) {
*
* By default, 32 events are persisted.
*/
public int getMaxPersistedEvents() {
return impl.getMaxPersistedEvents();
public int getMaxPersistedEvents() {
return impl.getMaxPersistedEvents();
}

/**
Expand All @@ -550,7 +551,7 @@ public int getMaxPersistedEvents() {
*
* By default, 32 events are persisted.
*/
public void setMaxPersistedEvents(int maxPersistedEvents) {
public void setMaxPersistedEvents(@IntRange(from = 0) int maxPersistedEvents) {
if (maxPersistedEvents >= 0) {
impl.setMaxPersistedEvents(maxPersistedEvents);
} else {
Expand All @@ -576,7 +577,7 @@ public int getMaxReportedThreads() {
*
* By default, up to 200 threads are reported.
*/
public void setMaxReportedThreads(int maxReportedThreads) {
public void setMaxReportedThreads(@IntRange(from = 0) int maxReportedThreads) {
if (maxReportedThreads >= 0) {
impl.setMaxReportedThreads(maxReportedThreads);
} else {
Expand All @@ -602,7 +603,7 @@ public int getMaxPersistedSessions() {
*
* By default, 128 sessions are persisted.
*/
public void setMaxPersistedSessions(int maxPersistedSessions) {
public void setMaxPersistedSessions(@IntRange(from = 0) int maxPersistedSessions) {
if (maxPersistedSessions >= 0) {
impl.setMaxPersistedSessions(maxPersistedSessions);
} else {
Expand All @@ -628,7 +629,7 @@ public int getMaxStringValueLength() {
*
* By default, the limit is 10,000.
*/
public void setMaxStringValueLength(int maxStringValueLength) {
public void setMaxStringValueLength(@IntRange(from = 0) int maxStringValueLength) {
if (maxStringValueLength >= 0) {
impl.setMaxStringValueLength(maxStringValueLength);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bugsnag.android

import android.os.Environment
import com.bugsnag.android.internal.BackgroundTaskService
import com.bugsnag.android.internal.dag.ConfigModule
import com.bugsnag.android.internal.dag.ContextModule
import com.bugsnag.android.internal.dag.DependencyModule
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/bugsnag/android/DeliveryDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import static com.bugsnag.android.SeverityReason.REASON_PROMISE_REJECTION;

import com.bugsnag.android.internal.BackgroundTaskService;
import com.bugsnag.android.internal.ImmutableConfig;
import com.bugsnag.android.internal.TaskType;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/bugsnag/android/DeviceDataCollector.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import android.content.res.Resources
import android.os.BatteryManager
import android.os.Build
import android.provider.Settings
import com.bugsnag.android.internal.BackgroundTaskService
import com.bugsnag.android.internal.TaskType
import java.io.File
import java.util.Date
import java.util.Locale
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.bugsnag.android

import com.bugsnag.android.internal.BackgroundTaskService
import com.bugsnag.android.internal.dag.ConfigModule
import com.bugsnag.android.internal.dag.ContextModule
import com.bugsnag.android.internal.dag.DependencyModule
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/bugsnag/android/EventStore.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.bugsnag.android;

import com.bugsnag.android.internal.BackgroundTaskService;
import com.bugsnag.android.internal.ImmutableConfig;
import com.bugsnag.android.internal.TaskType;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import static com.bugsnag.android.DeliveryHeadersKt.HEADER_INTERNAL_ERROR;
import static com.bugsnag.android.SeverityReason.REASON_UNHANDLED_EXCEPTION;

import com.bugsnag.android.internal.BackgroundTaskService;
import com.bugsnag.android.internal.ImmutableConfig;
import com.bugsnag.android.internal.JsonHelper;
import com.bugsnag.android.internal.TaskType;

import android.annotation.SuppressLint;
import android.content.Context;
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/bugsnag/android/LibraryLoader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.bugsnag.android;

import com.bugsnag.android.internal.TaskType;

import java.util.concurrent.atomic.AtomicBoolean;

class LibraryLoader {
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/com/bugsnag/android/NativeInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,14 @@ public static void addMetadata(@NonNull final String tab,
getClient().addMetadata(tab, key, value);
}

/**
* Add metadata to subsequent exception reports with a Hashmap
*/
public static void addMetadata(@NonNull final String tab,
@NonNull final Map<String, ?> metadata) {
getClient().addMetadata(tab, metadata);
}

/**
* Return the client report release stage
*/
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/bugsnag/android/Notifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.io.IOException
*/
class Notifier @JvmOverloads constructor(
var name: String = "Android Bugsnag Notifier",
var version: String = "5.28.2",
var version: String = "5.30.0",
var url: String = "https://bugsnag.com"
) : JsonStream.Streamable {

Expand Down
13 changes: 7 additions & 6 deletions app/src/main/java/com/bugsnag/android/PluginClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ internal class PluginClient(
}

private val plugins: Set<Plugin>

private val ndkPlugin = instantiatePlugin(NDK_PLUGIN)
private val anrPlugin = instantiatePlugin(ANR_PLUGIN)
private val rnPlugin = instantiatePlugin(RN_PLUGIN)
private val ndkPlugin = instantiatePlugin(NDK_PLUGIN, immutableConfig.enabledErrorTypes.ndkCrashes)
private val anrPlugin = instantiatePlugin(ANR_PLUGIN, immutableConfig.enabledErrorTypes.anrs)
private val rnPlugin = instantiatePlugin(RN_PLUGIN, immutableConfig.enabledErrorTypes.unhandledRejections)

init {
val set = mutableSetOf<Plugin>()
Expand All @@ -32,12 +31,14 @@ internal class PluginClient(
plugins = set.toSet()
}

private fun instantiatePlugin(clz: String): Plugin? {
private fun instantiatePlugin(clz: String, isWarningEnabled: Boolean): Plugin? {
return try {
val pluginClz = Class.forName(clz)
pluginClz.newInstance() as Plugin
} catch (exc: ClassNotFoundException) {
logger.d("Plugin '$clz' is not on the classpath - functionality will not be enabled.")
if (isWarningEnabled) {
logger.d("Plugin '$clz' is not on the classpath - functionality will not be enabled.")
}
null
} catch (exc: Throwable) {
logger.e("Failed to load plugin '$clz'", exc)
Expand Down
25 changes: 17 additions & 8 deletions app/src/main/java/com/bugsnag/android/RootDetector.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.bugsnag.android

import androidx.annotation.VisibleForTesting
import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.util.concurrent.atomic.AtomicBoolean
import java.io.Reader

/**
* Attempts to detect whether the device is rooted. Root detection errs on the side of false
Expand Down Expand Up @@ -41,12 +40,13 @@ internal class RootDetector @JvmOverloads constructor(
)
}

private val libraryLoaded = AtomicBoolean(false)
@Volatile
private var libraryLoaded = false

init {
try {
System.loadLibrary("bugsnag-root-detection")
libraryLoaded.set(true)
libraryLoaded = true
} catch (ignored: UnsatisfiedLinkError) {
// library couldn't load. This could be due to root detection countermeasures,
// or down to genuine OS level bugs with library loading - in either case
Expand Down Expand Up @@ -107,7 +107,7 @@ internal class RootDetector @JvmOverloads constructor(
line.replace("\\s".toRegex(), "")
}.filter { line ->
line.startsWith("ro.debuggable=[1]") || line.startsWith("ro.secure=[0]")
}.count() > 0
}.any()
}
}
return false
Expand All @@ -120,8 +120,7 @@ internal class RootDetector @JvmOverloads constructor(
var process: Process? = null
return try {
process = processBuilder.start()
val output = process.inputStream.bufferedReader().use(BufferedReader::readText)
output.isNotBlank()
process.inputStream.bufferedReader().use { it.isNotBlank() }
} catch (ignored: IOException) {
false
} finally {
Expand All @@ -131,11 +130,21 @@ internal class RootDetector @JvmOverloads constructor(

private external fun performNativeRootChecks(): Boolean

private fun Reader.isNotBlank(): Boolean {
while (true) {
val ch = read()
when {
ch == -1 -> return false
!ch.toChar().isWhitespace() -> return true
}
}
}

/**
* Performs root checks which require native code.
*/
private fun nativeCheckRoot(): Boolean = when {
libraryLoaded.get() -> performNativeRootChecks()
libraryLoaded -> performNativeRootChecks()
else -> false
}
}
Loading

0 comments on commit 21c71ff

Please sign in to comment.