diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml
index 39928e0f18..b5e71d8abe 100644
--- a/.buildkite/pipeline.full.yml
+++ b/.buildkite/pipeline.full.yml
@@ -39,7 +39,9 @@ steps:
# BitBar steps
#
+ # Minimal tests job skipped as there are only ANR scenarios, run separately using BS
- label: ':bitbar: Minimal fixture end-to-end tests'
+ skip: "Only ANR scenarios are run again the minimal fixture at present"
depends_on: "fixture-minimal"
timeout_in_minutes: 30
plugins:
@@ -62,6 +64,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
concurrency: 25
concurrency_group: 'bitbar'
concurrency_method: eager
@@ -86,11 +95,20 @@ steps:
- "--farm=bs"
- "--device=ANDROID_9"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
concurrency: 5
concurrency_group: 'browserstack-app'
concurrency_method: eager
+ # Minimal tests job skipped as there are only ANR scenarios, run separately using BS
- label: ':bitbar: Debug fixture smoke tests'
+ skip: "Only ANR scenarios are run again the minimal fixture at present"
depends_on: "fixture-debug"
timeout_in_minutes: 30
plugins:
@@ -116,6 +134,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-debug"
concurrency: 25
@@ -144,6 +169,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_9"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-debug"
concurrency: 5
@@ -178,6 +210,13 @@ steps:
- "--exclude=features/full_tests/[^a-k].*.feature"
- "--exclude=features/full_tests/anr.feature"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 25
@@ -211,6 +250,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 25
@@ -242,6 +288,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_7"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 5
@@ -274,6 +327,13 @@ steps:
- "--exclude=features/full_tests/[^a-k].*.feature"
- "--exclude=features/full_tests/anr.feature"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 25
@@ -306,6 +366,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 25
@@ -335,6 +402,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_8"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 5
@@ -369,6 +443,13 @@ steps:
- "--exclude=features/full_tests/[^a-k].*.feature"
- "--exclude=features/full_tests/anr.feature"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -403,6 +484,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -434,6 +522,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_9"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -468,6 +563,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -502,6 +604,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -532,6 +641,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_10"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -570,6 +686,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -604,6 +727,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -634,6 +764,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_11"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -668,6 +805,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -702,6 +846,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -732,6 +883,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_13"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -766,6 +924,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -800,6 +965,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -830,6 +1002,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_14"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml
index 3839238e47..baf34f0931 100644
--- a/.buildkite/pipeline.yml
+++ b/.buildkite/pipeline.yml
@@ -130,6 +130,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 25
@@ -160,6 +167,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_7"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 5
@@ -191,6 +205,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 25
@@ -219,6 +240,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_8"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r19"
concurrency: 5
@@ -252,6 +280,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -315,6 +350,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -345,6 +387,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_10"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -379,6 +428,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -410,6 +466,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_11"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -449,6 +512,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -480,6 +550,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_12"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -515,6 +592,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -548,6 +632,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -578,6 +669,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_13"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
@@ -611,6 +709,13 @@ steps:
- "--no-tunnel"
- "--aws-public-ip"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 25
@@ -641,6 +746,13 @@ steps:
- "--farm=bs"
- "--device=ANDROID_14"
- "--fail-fast"
+ - "--format=junit"
+ - "--out=reports"
+ - "--format=pretty"
+ test-collector#v1.10.2:
+ files: "reports/TEST-*.xml"
+ format: "junit"
+ branch: "^master|next$$"
env:
TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21"
concurrency: 5
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fbfa4b275d..4d7fa3c995 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,14 @@
* Add original error class and message to metadata for link errors loading BugSnag libraries
[#2070](https://github.com/bugsnag/bugsnag-android/pull/2070)
+### Bug fixes
+
+* Sending startup crashes synchronously now uses a flexible timeout so that apps with slower startups don't ANR
+ [#2075](https://github.com/bugsnag/bugsnag-android/pull/2075)
+ [#2080](https://github.com/bugsnag/bugsnag-android/pull/2080)
+* Work around a possible platform NullPointerException when calling `Intent.getExtras` (https://github.com/bugsnag/bugsnag-android/issues/2082)
+ [#2083](https://github.com/bugsnag/bugsnag-android/pull/2083)
+
## 6.7.0 (2024-08-08)
### Enhancements
diff --git a/bugsnag-android-core/detekt-baseline.xml b/bugsnag-android-core/detekt-baseline.xml
index 80214ff537..e4e75d4c39 100644
--- a/bugsnag-android-core/detekt-baseline.xml
+++ b/bugsnag-android-core/detekt-baseline.xml
@@ -49,6 +49,7 @@
ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun updateSeverityReason(@SeverityReason.SeverityReasonType reason: String)
ReturnCount:DefaultDelivery.kt$DefaultDelivery$fun deliver( urlString: String, json: ByteArray, headers: Map<String, String?> ): DeliveryStatus
SpreadOperator:FileStore.kt$FileStore$(*listFiles)
+ SwallowedException:ActivityBreadcrumbCollector.kt$ActivityBreadcrumbCollector$re: Exception
SwallowedException:AppDataCollector.kt$AppDataCollector$e: Exception
SwallowedException:BugsnagEventMapper.kt$BugsnagEventMapper$pe: IllegalArgumentException
SwallowedException:ConnectivityCompat.kt$ConnectivityLegacy$e: NullPointerException
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/ActivityBreadcrumbCollector.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/ActivityBreadcrumbCollector.kt
index b97a2eb86a..0b031a729c 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/ActivityBreadcrumbCollector.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/ActivityBreadcrumbCollector.kt
@@ -79,6 +79,11 @@ internal class ActivityBreadcrumbCollector(
}
set("hasData", intent.data != null)
- set("hasExtras", intent.extras?.keySet()?.joinToString(", ") ?: false)
+
+ try {
+ set("hasExtras", intent.extras?.keySet()?.joinToString(", ") ?: false)
+ } catch (re: Exception) {
+ // deliberately ignore
+ }
}
}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventStore.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventStore.kt
index e6d8401ae9..5c3360dee9 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventStore.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventStore.kt
@@ -1,15 +1,16 @@
package com.bugsnag.android
+import android.os.SystemClock
import com.bugsnag.android.EventFilenameInfo.Companion.findTimestampInFilename
import com.bugsnag.android.EventFilenameInfo.Companion.fromEvent
import com.bugsnag.android.EventFilenameInfo.Companion.fromFile
import com.bugsnag.android.JsonStream.Streamable
import com.bugsnag.android.internal.BackgroundTaskService
+import com.bugsnag.android.internal.ForegroundDetector
import com.bugsnag.android.internal.ImmutableConfig
import com.bugsnag.android.internal.TaskType
import java.io.File
import java.util.Calendar
-import java.util.Comparator
import java.util.Date
import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
@@ -19,8 +20,7 @@ import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
/**
- * Store and flush Event reports which couldn't be sent immediately due to
- * lack of network connectivity.
+ * Store and flush Event reports.
*/
internal class EventStore(
private val config: ImmutableConfig,
@@ -42,7 +42,8 @@ internal class EventStore(
override val logger: Logger
/**
- * Flush startup crashes synchronously on the main thread
+ * Flush startup crashes synchronously on the main thread. Startup crashes block the main thread
+ * when being sent (subject to [Configuration.setSendLaunchCrashesSynchronously])
*/
fun flushOnLaunch() {
if (!config.sendLaunchCrashesSynchronously) {
@@ -58,13 +59,28 @@ internal class EventStore(
return
}
try {
- future.get(LAUNCH_CRASH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ // Calculate the maximum amount of time we are prepared to block while sending
+ // startup crashes, based on how long we think startup has taken so-far.
+ // This attempts to mitigate possible startup ANRs that can occur when other SDKs
+ // have blocked the main thread before this code is reached.
+ val currentStartupDuration =
+ SystemClock.elapsedRealtime() - ForegroundDetector.startupTime
+ var timeout = LAUNCH_CRASH_TIMEOUT_MS - currentStartupDuration
+
+ if (timeout <= 0) {
+ // if Bugsnag.start is called too long after Application.onCreate is expected to
+ // have returned, we use a full LAUNCH_CRASH_TIMEOUT_MS instead of a calculated one
+ // assuming that the app is already fully started
+ timeout = LAUNCH_CRASH_TIMEOUT_MS
+ }
+
+ future.get(timeout, TimeUnit.MILLISECONDS)
} catch (exc: InterruptedException) {
- logger.d("Failed to send launch crash reports within 2s timeout, continuing.", exc)
+ logger.d("Failed to send launch crash reports within timeout, continuing.", exc)
} catch (exc: ExecutionException) {
- logger.d("Failed to send launch crash reports within 2s timeout, continuing.", exc)
+ logger.d("Failed to send launch crash reports within timeout, continuing.", exc)
} catch (exc: TimeoutException) {
- logger.d("Failed to send launch crash reports within 2s timeout, continuing.", exc)
+ logger.d("Failed to send launch crash reports within timeout, continuing.", exc)
}
}
@@ -159,6 +175,7 @@ internal class EventStore(
deleteStoredFiles(setOf(eventFile))
logger.i("Deleting sent error file $eventFile.name")
}
+
DeliveryStatus.UNDELIVERED -> undeliveredEventPayload(eventFile)
DeliveryStatus.FAILURE -> {
val exc: Exception = RuntimeException("Failed to deliver event payload")
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/internal/ForegroundDetector.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/internal/ForegroundDetector.kt
index 4308c8ee9a..548c56ebdc 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/internal/ForegroundDetector.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/internal/ForegroundDetector.kt
@@ -55,6 +55,12 @@ internal object ForegroundDetector : ActivityLifecycleCallbacks, Handler.Callbac
private var waitingForActivityRestart: Boolean = false
+ /**
+ * Marks the timestamp (relative to [SystemClock.elapsedRealtime]) that we initialised for the
+ * first time.
+ */
+ internal val startupTime = SystemClock.elapsedRealtime()
+
@VisibleForTesting
internal var backgroundSent = true
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/ActivityLifecycleBreadcrumbTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/ActivityLifecycleBreadcrumbTest.kt
index d0e2931e36..6f96abf640 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/ActivityLifecycleBreadcrumbTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/ActivityLifecycleBreadcrumbTest.kt
@@ -1,6 +1,7 @@
package com.bugsnag.android
import android.app.Activity
+import android.content.Intent
import android.os.Bundle
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
@@ -10,6 +11,8 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnitRunner
@RunWith(MockitoJUnitRunner::class)
@@ -120,4 +123,15 @@ internal class ActivityLifecycleBreadcrumbTest {
tracker.onActivityStarted(activity2)
assertEquals("onCreate()", resultMetadata!!["previous"])
}
+
+ @Test
+ fun failGetExtras() {
+ val mockIntent = mock(Intent::class.java)
+ `when`(mockIntent.extras).thenThrow(NullPointerException())
+ `when`(activity.intent).thenReturn(mockIntent)
+
+ tracker.onActivityCreated(activity, null)
+ assertFalse(resultMetadata!!["hasBundle"] as Boolean)
+ assertFalse(resultMetadata!!["hasData"] as Boolean)
+ }
}
diff --git a/docker-compose.yml b/docker-compose.yml
index 0b1b4d07fe..3a1a174510 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -61,6 +61,7 @@ services:
- ./build:/app/build
- ./features/:/app/features/
- ./maze_output:/app/maze_output
+ - ./reports/:/app/reports/
- /var/run/docker.sock:/var/run/docker.sock
android-license-audit: