Skip to content

Commit 73ddccb

Browse files
authored
Merge pull request #2396 from bugsnag/release/v6.25.0
Release v6.25.0
2 parents 1185a94 + 7abb05c commit 73ddccb

63 files changed

Lines changed: 1076 additions & 256 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
4848
with:
4949
submodules: recursive
50-
- uses: gradle/actions/wrapper-validation@f29f5a9d7b09a7c6b29859002d29d24e1674c884 #v5.0.1
50+
- uses: gradle/actions/wrapper-validation@0723195856401067f7a2779048b490ace7a47d7c #v5.0.2
5151

5252
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0
5353
with:
@@ -64,7 +64,7 @@ jobs:
6464

6565
# Initializes the CodeQL tools for scanning.
6666
- name: Initialize CodeQL
67-
uses: github/codeql-action/init@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 #v4.32.2
67+
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e #v4.32.4
6868
with:
6969
languages: ${{ matrix.language }}
7070
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -83,6 +83,6 @@ jobs:
8383
./gradlew --no-daemon assemble
8484
8585
- name: Perform CodeQL Analysis
86-
uses: github/codeql-action/analyze@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 #v4.32.2
86+
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e #v4.32.4
8787
with:
8888
category: "/language:${{matrix.language}}"

.github/workflows/scorecard.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
# Upload the results to GitHub's code scanning dashboard (optional).
6969
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
7070
- name: "Upload to code-scanning"
71-
uses: github/codeql-action/upload-sarif@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
71+
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
7272
with:
7373
sarif_file: results.sarif
7474

@@ -77,4 +77,4 @@ jobs:
7777
runs-on: ubuntu-latest
7878
steps:
7979
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
80-
- uses: gradle/actions/wrapper-validation@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
80+
- uses: gradle/actions/wrapper-validation@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Changelog
22

3+
## 6.25.0 (2026-03-02)
4+
5+
### Enhancements
6+
7+
* Added `NativeOutOfMemoryPlugin` as a new way to report `OutOfMemoryError`s that uses pre-allocated memory in the NDK module instead of allocating an `Event` object. When used `OutOfMemoryError`s will be more reliably reported, but will not be passed to `OnErrorCallback`s (`OnSendCallback` works as expected).
8+
[#2384](https://github.com/bugsnag/bugsnag-android/pull/2384)
9+
* Added `appHangCooldownMillis` to the AppHangPlugin to control the number of AppHang errors produced when the app is performance constrained
10+
[#2389](https://github.com/bugsnag/bugsnag-android/pull/2389)
11+
* Moved root/jailbreak detection onto a background thread so that it no longer blocks startup (this should improve startup performance in most common cases)
12+
[#2391](https://github.com/bugsnag/bugsnag-android/pull/2391)
13+
14+
### Bug Fixes
15+
16+
* Reduced the heartbeat overheads of `BugsnagAppHangPlugin` reducing both the CPU cost of a heartbeat and the frequency.
17+
[#2395](https://github.com/bugsnag/bugsnag-android/pull/2395)
18+
319
## 6.24.0 (2026-02-11)
420

521
### Enhancements

Gemfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ source "https://rubygems.org"
44
#gem 'bugsnag-maze-runner', path: '../maze-runner'
55

66
# Or a specific release:
7-
gem 'bugsnag-maze-runner', '~>10.0'
7+
gem 'bugsnag-maze-runner', '~>11.0'
88

99
# Or follow master:
1010
#gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner'
1111

1212
gem "license_finder", "~> 7.0"
13-
14-
gem "openssl", "~> 4.0"

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,6 @@ endif
8585

8686
.PHONY: check
8787
check:
88-
@./gradlew lint detekt ktlintCheck checkstyle
88+
@./gradlew lint detekt ktlintCheck checkstyle apiCheck
8989
@./scripts/run-cpp-check.sh
9090
@./scripts/run-clang-format-ci-check.sh

bugsnag-android-core/api/bugsnag-android-core.api

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public final class com/bugsnag/android/Bugsnag {
8888
public static fun getLastRunInfo ()Lcom/bugsnag/android/LastRunInfo;
8989
public static fun getMetadata (Ljava/lang/String;)Ljava/util/Map;
9090
public static fun getMetadata (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
91+
public static fun getOutOfMemoryHandler ()Lcom/bugsnag/android/OutOfMemoryHandler;
9192
public static fun getUser ()Lcom/bugsnag/android/User;
9293
public static fun isStarted ()Z
9394
public static fun leaveBreadcrumb (Ljava/lang/String;)V
@@ -103,6 +104,7 @@ public final class com/bugsnag/android/Bugsnag {
103104
public static fun resumeSession ()Z
104105
public static fun setContext (Ljava/lang/String;)V
105106
public static fun setGroupingDiscriminator (Ljava/lang/String;)Ljava/lang/String;
107+
public static fun setOutOfMemoryHandler (Lcom/bugsnag/android/OutOfMemoryHandler;)V
106108
public static fun setUser (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
107109
public static fun start (Landroid/content/Context;)Lcom/bugsnag/android/Client;
108110
public static fun start (Landroid/content/Context;Lcom/bugsnag/android/Configuration;)Lcom/bugsnag/android/Client;
@@ -147,6 +149,7 @@ public class com/bugsnag/android/Client : com/bugsnag/android/CallbackAware, com
147149
public fun getLastRunInfo ()Lcom/bugsnag/android/LastRunInfo;
148150
public fun getMetadata (Ljava/lang/String;)Ljava/util/Map;
149151
public fun getMetadata (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
152+
public fun getOutOfMemoryHandler ()Lcom/bugsnag/android/OutOfMemoryHandler;
150153
public fun getUser ()Lcom/bugsnag/android/User;
151154
public fun leaveBreadcrumb (Ljava/lang/String;)V
152155
public fun leaveBreadcrumb (Ljava/lang/String;Ljava/util/Map;Lcom/bugsnag/android/BreadcrumbType;)V
@@ -161,6 +164,7 @@ public class com/bugsnag/android/Client : com/bugsnag/android/CallbackAware, com
161164
public fun resumeSession ()Z
162165
public fun setContext (Ljava/lang/String;)V
163166
public fun setGroupingDiscriminator (Ljava/lang/String;)Ljava/lang/String;
167+
public fun setOutOfMemoryHandler (Lcom/bugsnag/android/OutOfMemoryHandler;)V
164168
public fun setUser (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
165169
public fun startSession ()V
166170
}
@@ -700,6 +704,10 @@ public abstract interface class com/bugsnag/android/OnSessionCallback {
700704
public abstract fun onSession (Lcom/bugsnag/android/Session;)Z
701705
}
702706

707+
public abstract interface class com/bugsnag/android/OutOfMemoryHandler {
708+
public abstract fun onOutOfMemory (Ljava/lang/OutOfMemoryError;)Z
709+
}
710+
703711
public abstract interface class com/bugsnag/android/Plugin {
704712
public abstract fun load (Lcom/bugsnag/android/Client;)V
705713
public abstract fun unload ()V
@@ -869,6 +877,10 @@ public final class com/bugsnag/android/StateEvent$StartSession : com/bugsnag/and
869877
public final fun getUnhandledCount ()I
870878
}
871879

880+
public final class com/bugsnag/android/StateEvent$SynchronizeState : com/bugsnag/android/StateEvent {
881+
public static final field INSTANCE Lcom/bugsnag/android/StateEvent$SynchronizeState;
882+
}
883+
872884
public final class com/bugsnag/android/StateEvent$UpdateContext : com/bugsnag/android/StateEvent {
873885
public final field context Ljava/lang/String;
874886
public fun <init> (Ljava/lang/String;)V
@@ -1171,13 +1183,15 @@ public final class com/bugsnag/android/internal/TaskType : java/lang/Enum {
11711183
public abstract interface class com/bugsnag/android/internal/dag/Provider {
11721184
public abstract fun get ()Ljava/lang/Object;
11731185
public abstract fun getOrNull ()Ljava/lang/Object;
1186+
public abstract fun isComplete ()Z
11741187
}
11751188

11761189
public abstract class com/bugsnag/android/internal/dag/RunnableProvider : com/bugsnag/android/internal/dag/Provider, java/lang/Runnable {
11771190
public fun <init> ()V
11781191
public fun get ()Ljava/lang/Object;
11791192
public fun getOrNull ()Ljava/lang/Object;
11801193
public abstract fun invoke ()Ljava/lang/Object;
1194+
public fun isComplete ()Z
11811195
public final fun run ()V
11821196
}
11831197

@@ -1189,6 +1203,7 @@ public final class com/bugsnag/android/internal/dag/ValueProvider : com/bugsnag/
11891203
public fun get ()Ljava/lang/Object;
11901204
public fun getOrNull ()Ljava/lang/Object;
11911205
public fun hashCode ()I
1206+
public fun isComplete ()Z
11921207
public fun toString ()Ljava/lang/String;
11931208
}
11941209

bugsnag-android-core/detekt-baseline.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<ID>LongParameterList:AppWithState.kt$AppWithState$( binaryArch: String?, id: String?, releaseStage: String?, version: String?, codeBundleId: String?, buildUuid: Provider&lt;String?>?, type: String?, versionCode: Number?, /** * The number of milliseconds the application was running before the event occurred */ var duration: Number?, /** * The number of milliseconds the application was running in the foreground before the * event occurred */ var durationInForeground: Number?, /** * Whether the application was in the foreground when the event occurred */ var inForeground: Boolean?, /** * Whether the application was launching when the event occurred */ var isLaunching: Boolean? )</ID>
1616
<ID>LongParameterList:AppWithState.kt$AppWithState$( binaryArch: String?, id: String?, releaseStage: String?, version: String?, codeBundleId: String?, buildUuid: String?, type: String?, versionCode: Number?, /** * The number of milliseconds the application was running before the event occurred */ duration: Number?, /** * The number of milliseconds the application was running in the foreground before the * event occurred */ durationInForeground: Number?, /** * Whether the application was in the foreground when the event occurred */ inForeground: Boolean?, /** * Whether the application was launching when the event occurred */ isLaunching: Boolean? )</ID>
1717
<ID>LongParameterList:AppWithState.kt$AppWithState$( config: ImmutableConfig, binaryArch: String?, id: String?, releaseStage: String?, version: String?, codeBundleId: String?, duration: Number?, durationInForeground: Number?, inForeground: Boolean?, isLaunching: Boolean? )</ID>
18-
<ID>LongParameterList:DataCollectionModule.kt$DataCollectionModule$( contextModule: ContextModule, configModule: ConfigModule, systemServiceModule: SystemServiceModule, trackerModule: TrackerModule, bgTaskService: BackgroundTaskService, connectivity: Connectivity, deviceIdStore: Provider&lt;DeviceIdStore>, memoryTrimState: MemoryTrimState )</ID>
18+
<ID>LongParameterList:DataCollectionModule.kt$DataCollectionModule$( contextModule: ContextModule, configModule: ConfigModule, systemServiceModule: SystemServiceModule, trackerModule: TrackerModule, bgTaskService: BackgroundTaskService, connectivity: Connectivity, deviceId: Provider&lt;DeviceIdStore.DeviceIds?>, memoryTrimState: MemoryTrimState, clientObservable: ClientObservable )</ID>
1919
<ID>LongParameterList:Device.kt$Device$( buildInfo: DeviceBuildInfo, /** * The Application Binary Interface used */ var cpuAbi: Array&lt;String>?, /** * Whether the device has been jailbroken */ var jailbroken: Boolean?, /** * A UUID generated by Bugsnag and used for the individual application on a device */ var id: String?, /** * The IETF language tag of the locale used */ var locale: String?, /** * The total number of bytes of memory on the device */ var totalMemory: Long?, /** * A collection of names and their versions of the primary languages, frameworks or * runtimes that the application is running on */ runtimeVersions: MutableMap&lt;String, Any>? )</ID>
2020
<ID>LongParameterList:DeviceBuildInfo.kt$DeviceBuildInfo$( val manufacturer: String?, val model: String?, val osVersion: String?, val apiLevel: Int?, val osBuild: String?, val fingerprint: String?, val tags: String?, val brand: String?, val cpuAbis: Array&lt;String>? )</ID>
2121
<ID>LongParameterList:DeviceDataCollector.kt$DeviceDataCollector$( private val connectivity: Connectivity, private val appContext: Context, resources: Resources, private val deviceIdStore: Provider&lt;DeviceIdStore.DeviceIds?>, private val buildInfo: DeviceBuildInfo, private val dataDirectory: File, private val rootedFuture: Provider&lt;Boolean>?, private val bgTaskService: BackgroundTaskService, private val logger: Logger )</ID>
@@ -84,7 +84,6 @@
8484
<ID>SwallowedException:ConnectivityCompat.kt$ConnectivityLegacy$e: NullPointerException</ID>
8585
<ID>SwallowedException:ContextExtensions.kt$exc: RuntimeException</ID>
8686
<ID>SwallowedException:DeviceDataCollector.kt$DeviceDataCollector$e: Throwable</ID>
87-
<ID>SwallowedException:DeviceDataCollector.kt$DeviceDataCollector$exc: Exception</ID>
8887
<ID>SwallowedException:DeviceDataCollector.kt$DeviceDataCollector$exception: Exception</ID>
8988
<ID>SwallowedException:DeviceIdFilePersistence.kt$DeviceIdFilePersistence$exc: OverlappingFileLockException</ID>
9089
<ID>SwallowedException:EventStore.kt$EventStore$exception: RejectedExecutionException</ID>

bugsnag-android-core/src/main/java/com/bugsnag/android/Bugsnag.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,26 @@ public static void clearFeatureFlags() {
498498
getClient().clearFeatureFlags();
499499
}
500500

501+
/**
502+
* Override or intercept the default error handling for {@link OutOfMemoryError}s.
503+
*
504+
* @param handler the new handler to use (or null to revert to normal error handling for OOMs)
505+
* @see #getOutOfMemoryHandler()
506+
*/
507+
public static void setOutOfMemoryHandler(@Nullable OutOfMemoryHandler handler) {
508+
getClient().setOutOfMemoryHandler(handler);
509+
}
510+
511+
/**
512+
* Return the currently defined {@link OutOfMemoryHandler} if one is being used.
513+
*
514+
* @return the current {@code OutOfMemoryHandler} or null if none is set
515+
*/
516+
@Nullable
517+
public static OutOfMemoryHandler getOutOfMemoryHandler() {
518+
return getClient().getOutOfMemoryHandler();
519+
}
520+
501521
/**
502522
* Get the current Bugsnag Client instance.
503523
*/

bugsnag-android-core/src/main/java/com/bugsnag/android/Client.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public Client(@NonNull Context androidContext, @NonNull String apiKey) {
128128
* @param configuration a configuration for the Client
129129
*/
130130
public Client(@NonNull Context androidContext, @NonNull final Configuration configuration) {
131-
ContextModule contextModule = new ContextModule(androidContext, bgTaskService);
131+
ContextModule contextModule = new ContextModule(androidContext);
132132
appContext = contextModule.getCtx();
133133

134134
notifier = configuration.getNotifier();
@@ -186,16 +186,16 @@ public Unit invoke(Boolean hasConnection, String networkState) {
186186

187187
// lookup system services
188188
final SystemServiceModule systemServiceModule =
189-
new SystemServiceModule(contextModule, bgTaskService);
189+
new SystemServiceModule(contextModule);
190190

191191
// setup further state trackers and data collection
192192
TrackerModule trackerModule = new TrackerModule(configModule,
193193
storageModule, this, bgTaskService, callbackState);
194194

195195
DataCollectionModule dataCollectionModule = new DataCollectionModule(contextModule,
196196
configModule, systemServiceModule, trackerModule,
197-
bgTaskService, connectivity, storageModule.getDeviceIdStore(),
198-
memoryTrimState);
197+
bgTaskService, connectivity, storageModule.getDeviceId(),
198+
memoryTrimState, clientObservable);
199199

200200
// load the device + user information
201201
userState = storageModule.loadUser(configuration.getUser());
@@ -938,6 +938,31 @@ void notifyInternalWithErrorOptions(@NonNull Event event,
938938
}
939939
}
940940

941+
/**
942+
* Override or intercept the default error handling for {@link OutOfMemoryError}s.
943+
*
944+
* @param handler the new handler to use (or null to revert to normal error handling for OOMs)
945+
* @see #getOutOfMemoryHandler()
946+
*/
947+
public void setOutOfMemoryHandler(@Nullable OutOfMemoryHandler handler) {
948+
if (exceptionHandler != null) {
949+
exceptionHandler.setOutOfMemoryHandler(handler);
950+
}
951+
}
952+
953+
/**
954+
* Return the currently defined {@link OutOfMemoryHandler} if one is being used.
955+
*
956+
* @return the current {@code OutOfMemoryHandler} or null if none is set
957+
*/
958+
@Nullable
959+
public OutOfMemoryHandler getOutOfMemoryHandler() {
960+
if (exceptionHandler == null) {
961+
return null;
962+
}
963+
return exceptionHandler.getOutOfMemoryHandler();
964+
}
965+
941966
/**
942967
* Returns the current buffer of breadcrumbs that will be sent with captured events. This
943968
* ordered list represents the most recent breadcrumbs to be captured up to the limit

bugsnag-android-core/src/main/java/com/bugsnag/android/ClientObservable.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ internal class ClientObservable : BaseObservable() {
3131
fun postNdkDeliverPending() {
3232
updateState { StateEvent.DeliverPending }
3333
}
34+
35+
fun postSynchronizeState() {
36+
updateState { StateEvent.SynchronizeState }
37+
}
3438
}

0 commit comments

Comments
 (0)