mirror of https://github.com/M66B/FairEmail.git
1181 lines
41 KiB
Java
1181 lines
41 KiB
Java
package com.bugsnag.android;
|
|
|
|
import android.content.Context;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.VisibleForTesting;
|
|
|
|
import java.io.File;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* User-specified configuration storage object, contains information
|
|
* specified at the client level, api-key and endpoint configuration.
|
|
*/
|
|
@SuppressWarnings("ConstantConditions") // suppress warning about making redundant null checks
|
|
public class Configuration implements CallbackAware, MetadataAware, UserAware, FeatureFlagAware {
|
|
|
|
private static final int MIN_BREADCRUMBS = 0;
|
|
private static final int MAX_BREADCRUMBS = 500;
|
|
private static final int VALID_API_KEY_LEN = 32;
|
|
private static final long MIN_LAUNCH_CRASH_THRESHOLD_MS = 0;
|
|
|
|
final ConfigInternal impl;
|
|
|
|
/**
|
|
* Constructs a new Configuration object with default values.
|
|
*/
|
|
public Configuration(@NonNull String apiKey) {
|
|
validateApiKey(apiKey);
|
|
impl = new ConfigInternal(apiKey);
|
|
}
|
|
|
|
/**
|
|
* Loads a Configuration object from values supplied as meta-data elements in your
|
|
* AndroidManifest.
|
|
*/
|
|
@NonNull
|
|
public static Configuration load(@NonNull Context context) {
|
|
return ConfigInternal.load(context);
|
|
}
|
|
|
|
@NonNull
|
|
static Configuration load(@NonNull Context context, @NonNull String apiKey) {
|
|
return ConfigInternal.load(context, apiKey);
|
|
}
|
|
|
|
private void validateApiKey(String value) {
|
|
if (isInvalidApiKey(value)) {
|
|
DebugLogger.INSTANCE.w("Invalid configuration. "
|
|
+ "apiKey should be a 32-character hexademical string, got " + value);
|
|
}
|
|
}
|
|
|
|
@VisibleForTesting
|
|
static boolean isInvalidApiKey(String apiKey) {
|
|
if (Intrinsics.isEmpty(apiKey)) {
|
|
throw new IllegalArgumentException("No Bugsnag API Key set");
|
|
}
|
|
if (apiKey.length() != VALID_API_KEY_LEN) {
|
|
return true;
|
|
}
|
|
// check whether each character is hexadecimal (either a digit or a-f).
|
|
// this avoids using a regex to improve startup performance.
|
|
for (int k = 0; k < VALID_API_KEY_LEN; k++) {
|
|
char chr = apiKey.charAt(k);
|
|
if (!Character.isDigit(chr) && (chr < 'a' || chr > 'f')) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void logNull(String property) {
|
|
getLogger().e("Invalid null value supplied to config." + property + ", ignoring");
|
|
}
|
|
|
|
/**
|
|
* Retrieves the API key used for events sent to Bugsnag.
|
|
*/
|
|
@NonNull
|
|
public String getApiKey() {
|
|
return impl.getApiKey();
|
|
}
|
|
|
|
/**
|
|
* Changes the API key used for events sent to Bugsnag.
|
|
*/
|
|
public void setApiKey(@NonNull String apiKey) {
|
|
validateApiKey(apiKey);
|
|
impl.setApiKey(apiKey);
|
|
}
|
|
|
|
/**
|
|
* Set the application version sent to Bugsnag. We'll automatically pull your app version
|
|
* from the versionName field in your AndroidManifest.xml file.
|
|
*/
|
|
@Nullable
|
|
public String getAppVersion() {
|
|
return impl.getAppVersion();
|
|
}
|
|
|
|
/**
|
|
* Set the application version sent to Bugsnag. We'll automatically pull your app version
|
|
* from the versionName field in your AndroidManifest.xml file.
|
|
*/
|
|
public void setAppVersion(@Nullable String appVersion) {
|
|
impl.setAppVersion(appVersion);
|
|
}
|
|
|
|
/**
|
|
* We'll automatically pull your versionCode from the versionCode field
|
|
* in your AndroidManifest.xml file. If you'd like to override this you
|
|
* can set this property.
|
|
*/
|
|
@Nullable
|
|
public Integer getVersionCode() {
|
|
return impl.getVersionCode();
|
|
}
|
|
|
|
/**
|
|
* We'll automatically pull your versionCode from the versionCode field
|
|
* in your AndroidManifest.xml file. If you'd like to override this you
|
|
* can set this property.
|
|
*/
|
|
public void setVersionCode(@Nullable Integer versionCode) {
|
|
impl.setVersionCode(versionCode);
|
|
}
|
|
|
|
/**
|
|
* If you would like to distinguish between errors that happen in different stages of the
|
|
* application release process (development, production, etc) you can set the releaseStage
|
|
* that is reported to Bugsnag.
|
|
*
|
|
* If you are running a debug build, we'll automatically set this to "development",
|
|
* otherwise it is set to "production". You can control whether events are sent for
|
|
* specific release stages using the enabledReleaseStages option.
|
|
*/
|
|
@Nullable
|
|
public String getReleaseStage() {
|
|
return impl.getReleaseStage();
|
|
}
|
|
|
|
/**
|
|
* If you would like to distinguish between errors that happen in different stages of the
|
|
* application release process (development, production, etc) you can set the releaseStage
|
|
* that is reported to Bugsnag.
|
|
*
|
|
* If you are running a debug build, we'll automatically set this to "development",
|
|
* otherwise it is set to "production". You can control whether events are sent for
|
|
* specific release stages using the enabledReleaseStages option.
|
|
*/
|
|
public void setReleaseStage(@Nullable String releaseStage) {
|
|
impl.setReleaseStage(releaseStage);
|
|
}
|
|
|
|
/**
|
|
* Controls whether we should capture and serialize the state of all threads at the time
|
|
* of an error.
|
|
*
|
|
* By default sendThreads is set to Thread.ThreadSendPolicy.ALWAYS. This can be set to
|
|
* Thread.ThreadSendPolicy.NEVER to disable or Thread.ThreadSendPolicy.UNHANDLED_ONLY
|
|
* to only do so for unhandled errors.
|
|
*/
|
|
@NonNull
|
|
public ThreadSendPolicy getSendThreads() {
|
|
return impl.getSendThreads();
|
|
}
|
|
|
|
/**
|
|
* Controls whether we should capture and serialize the state of all threads at the time
|
|
* of an error.
|
|
*
|
|
* By default sendThreads is set to Thread.ThreadSendPolicy.ALWAYS. This can be set to
|
|
* Thread.ThreadSendPolicy.NEVER to disable or Thread.ThreadSendPolicy.UNHANDLED_ONLY
|
|
* to only do so for unhandled errors.
|
|
*/
|
|
public void setSendThreads(@NonNull ThreadSendPolicy sendThreads) {
|
|
if (sendThreads != null) {
|
|
impl.setSendThreads(sendThreads);
|
|
} else {
|
|
logNull("sendThreads");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set whether or not Bugsnag should persist user information between application sessions.
|
|
*
|
|
* If enabled then any user information set will be re-used until the user information is
|
|
* removed manually by calling {@link Bugsnag#setUser(String, String, String)}
|
|
* with null arguments.
|
|
*/
|
|
public boolean getPersistUser() {
|
|
return impl.getPersistUser();
|
|
}
|
|
|
|
/**
|
|
* Set whether or not Bugsnag should persist user information between application sessions.
|
|
*
|
|
* If enabled then any user information set will be re-used until the user information is
|
|
* removed manually by calling {@link Bugsnag#setUser(String, String, String)}
|
|
* with null arguments.
|
|
*/
|
|
public void setPersistUser(boolean persistUser) {
|
|
impl.setPersistUser(persistUser);
|
|
}
|
|
|
|
/**
|
|
* Sets the directory where event and session JSON payloads should be persisted if a network
|
|
* request is not successful. If you use Bugsnag in multiple processes, then a unique
|
|
* persistenceDirectory <b>must</b> be configured for each process to prevent duplicate
|
|
* requests being made by each instantiation of Bugsnag.
|
|
* <p/>
|
|
* The persistenceDirectory also stores user information if {@link #getPersistUser()} has been
|
|
* set to true.
|
|
* <p/>
|
|
* By default, bugsnag sets the persistenceDirectory to {@link Context#getCacheDir()}.
|
|
* <p/>
|
|
* If the persistenceDirectory is changed between application launches, no attempt will be made
|
|
* to deliver events or sessions cached in the previous location.
|
|
*/
|
|
@Nullable
|
|
public File getPersistenceDirectory() {
|
|
return impl.getPersistenceDirectory();
|
|
}
|
|
|
|
/**
|
|
* Sets the directory where event and session JSON payloads should be persisted if a network
|
|
* request is not successful. If you use Bugsnag in multiple processes, then a unique
|
|
* persistenceDirectory <b>must</b> be configured for each process to prevent duplicate
|
|
* requests being made by each instantiation of Bugsnag.
|
|
* <p/>
|
|
* The persistenceDirectory also stores user information if {@link #getPersistUser()} has been
|
|
* set to true.
|
|
* <p/>
|
|
* By default, bugsnag sets the persistenceDirectory to {@link Context#getCacheDir()}.
|
|
* <p/>
|
|
* If the persistenceDirectory is changed between application launches, no attempt will be made
|
|
* to deliver events or sessions cached in the previous location.
|
|
*/
|
|
public void setPersistenceDirectory(@Nullable File directory) {
|
|
impl.setPersistenceDirectory(directory);
|
|
}
|
|
|
|
/**
|
|
* Deprecated. Use {@link #getLaunchDurationMillis()} instead.
|
|
*/
|
|
@Deprecated
|
|
public long getLaunchCrashThresholdMs() {
|
|
getLogger().w("The launchCrashThresholdMs configuration option is deprecated "
|
|
+ "and will be removed in a future release. Please use "
|
|
+ "launchDurationMillis instead.");
|
|
return getLaunchDurationMillis();
|
|
}
|
|
|
|
/**
|
|
* Deprecated. Use {@link #setLaunchDurationMillis(long)} instead.
|
|
*/
|
|
@Deprecated
|
|
public void setLaunchCrashThresholdMs(long launchCrashThresholdMs) {
|
|
getLogger().w("The launchCrashThresholdMs configuration option is deprecated "
|
|
+ "and will be removed in a future release. Please use "
|
|
+ "launchDurationMillis instead.");
|
|
setLaunchDurationMillis(launchCrashThresholdMs);
|
|
}
|
|
|
|
/**
|
|
* Sets whether or not Bugsnag should send crashes synchronously that occurred during
|
|
* the application's launch period. By default this behavior is enabled.
|
|
*
|
|
* See {@link #setLaunchDurationMillis(long)}
|
|
*/
|
|
public boolean getSendLaunchCrashesSynchronously() {
|
|
return impl.getSendLaunchCrashesSynchronously();
|
|
}
|
|
|
|
/**
|
|
* Sets whether or not Bugsnag should send crashes synchronously that occurred during
|
|
* the application's launch period. By default this behavior is enabled.
|
|
*
|
|
* See {@link #setLaunchDurationMillis(long)}
|
|
*/
|
|
public void setSendLaunchCrashesSynchronously(boolean sendLaunchCrashesSynchronously) {
|
|
impl.setSendLaunchCrashesSynchronously(sendLaunchCrashesSynchronously);
|
|
}
|
|
|
|
/**
|
|
* Sets the threshold in milliseconds for an uncaught error to be considered as a crash on
|
|
* launch. If a crash is detected on launch, Bugsnag will attempt to send the most recent
|
|
* event synchronously.
|
|
*
|
|
* 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 long getLaunchDurationMillis() {
|
|
return impl.getLaunchDurationMillis();
|
|
}
|
|
|
|
/**
|
|
* Sets the threshold in milliseconds for an uncaught error to be considered as a crash on
|
|
* launch. If a crash is detected on launch, Bugsnag will attempt to send the most recent
|
|
* event synchronously.
|
|
*
|
|
* 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) {
|
|
if (launchDurationMillis >= MIN_LAUNCH_CRASH_THRESHOLD_MS) {
|
|
impl.setLaunchDurationMillis(launchDurationMillis);
|
|
} else {
|
|
getLogger().e("Invalid configuration value detected. "
|
|
+ "Option launchDurationMillis should be a positive long value."
|
|
+ "Supplied value is " + launchDurationMillis);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets whether or not Bugsnag should automatically capture and report User sessions whenever
|
|
* the app enters the foreground.
|
|
*
|
|
* By default this behavior is enabled.
|
|
*/
|
|
public boolean getAutoTrackSessions() {
|
|
return impl.getAutoTrackSessions();
|
|
}
|
|
|
|
/**
|
|
* Sets whether or not Bugsnag should automatically capture and report User sessions whenever
|
|
* the app enters the foreground.
|
|
*
|
|
* By default this behavior is enabled.
|
|
*/
|
|
public void setAutoTrackSessions(boolean autoTrackSessions) {
|
|
impl.setAutoTrackSessions(autoTrackSessions);
|
|
}
|
|
|
|
/**
|
|
* Bugsnag will automatically detect different types of error in your application.
|
|
* If you wish to control exactly which types are enabled, set this property.
|
|
*/
|
|
@NonNull
|
|
public ErrorTypes getEnabledErrorTypes() {
|
|
return impl.getEnabledErrorTypes();
|
|
}
|
|
|
|
/**
|
|
* Bugsnag will automatically detect different types of error in your application.
|
|
* If you wish to control exactly which types are enabled, set this property.
|
|
*/
|
|
public void setEnabledErrorTypes(@NonNull ErrorTypes enabledErrorTypes) {
|
|
if (enabledErrorTypes != null) {
|
|
impl.setEnabledErrorTypes(enabledErrorTypes);
|
|
} else {
|
|
logNull("enabledErrorTypes");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If you want to disable automatic detection of all errors, you can set this property to false.
|
|
* By default this property is true.
|
|
*
|
|
* Setting autoDetectErrors to false will disable all automatic errors, regardless of the
|
|
* error types enabled by enabledErrorTypes
|
|
*/
|
|
public boolean getAutoDetectErrors() {
|
|
return impl.getAutoDetectErrors();
|
|
}
|
|
|
|
/**
|
|
* If you want to disable automatic detection of all errors, you can set this property to false.
|
|
* By default this property is true.
|
|
*
|
|
* Setting autoDetectErrors to false will disable all automatic errors, regardless of the
|
|
* error types enabled by enabledErrorTypes
|
|
*/
|
|
public void setAutoDetectErrors(boolean autoDetectErrors) {
|
|
impl.setAutoDetectErrors(autoDetectErrors);
|
|
}
|
|
|
|
/**
|
|
* If your app's codebase contains different entry-points/processes, but reports to a single
|
|
* Bugsnag project, you might want to add information denoting the type of process the error
|
|
* came from.
|
|
*
|
|
* This information can be used in the dashboard to filter errors and to determine whether
|
|
* an error is limited to a subset of appTypes.
|
|
*
|
|
* By default, this value is set to 'android'.
|
|
*/
|
|
@Nullable
|
|
public String getAppType() {
|
|
return impl.getAppType();
|
|
}
|
|
|
|
/**
|
|
* If your app's codebase contains different entry-points/processes, but reports to a single
|
|
* Bugsnag project, you might want to add information denoting the type of process the error
|
|
* came from.
|
|
*
|
|
* This information can be used in the dashboard to filter errors and to determine whether
|
|
* an error is limited to a subset of appTypes.
|
|
*
|
|
* By default, this value is set to 'android'.
|
|
*/
|
|
public void setAppType(@Nullable String appType) {
|
|
impl.setAppType(appType);
|
|
}
|
|
|
|
/**
|
|
* By default, the notifier's log messages will be logged using android.util.Log
|
|
* with a "Bugsnag" tag unless the releaseStage is "production".
|
|
*
|
|
* To override this behavior, an alternative instance can be provided that implements the
|
|
* Logger interface.
|
|
*/
|
|
@Nullable
|
|
public Logger getLogger() {
|
|
return impl.getLogger();
|
|
}
|
|
|
|
/**
|
|
* By default, the notifier's log messages will be logged using android.util.Log
|
|
* with a "Bugsnag" tag unless the releaseStage is "production".
|
|
*
|
|
* To override this behavior, an alternative instance can be provided that implements the
|
|
* Logger interface.
|
|
*/
|
|
public void setLogger(@Nullable Logger logger) {
|
|
impl.setLogger(logger);
|
|
}
|
|
|
|
/**
|
|
* The Delivery implementation used to make network calls to the Bugsnag
|
|
* <a href="https://docs.bugsnag.com/api/error-reporting/">Error Reporting</a> and
|
|
* <a href="https://docs.bugsnag.com/api/sessions/">Sessions API</a>.
|
|
*
|
|
* This may be useful if you have requirements such as certificate pinning and rotation,
|
|
* which are not supported by the default implementation.
|
|
*
|
|
* To provide custom delivery functionality, create a class which implements the Delivery
|
|
* interface. Please note that request bodies must match the structure specified in the
|
|
* <a href="https://docs.bugsnag.com/api/error-reporting/">Error Reporting</a> and
|
|
* <a href="https://docs.bugsnag.com/api/sessions/">Sessions API</a> documentation.
|
|
*
|
|
* You can use the return type from the deliver functions to control the strategy for
|
|
* retrying the transmission at a later date.
|
|
*
|
|
* If DeliveryStatus.UNDELIVERED is returned, the notifier will automatically cache
|
|
* the payload and trigger delivery later on. Otherwise, if either DeliveryStatus.DELIVERED
|
|
* or DeliveryStatus.FAILURE is returned the notifier will removed any cached payload
|
|
* and no further delivery will be attempted.
|
|
*/
|
|
@NonNull
|
|
public Delivery getDelivery() {
|
|
return impl.getDelivery();
|
|
}
|
|
|
|
/**
|
|
* The Delivery implementation used to make network calls to the Bugsnag
|
|
* <a href="https://docs.bugsnag.com/api/error-reporting/">Error Reporting</a> and
|
|
* <a href="https://docs.bugsnag.com/api/sessions/">Sessions API</a>.
|
|
*
|
|
* This may be useful if you have requirements such as certificate pinning and rotation,
|
|
* which are not supported by the default implementation.
|
|
*
|
|
* To provide custom delivery functionality, create a class which implements the Delivery
|
|
* interface. Please note that request bodies must match the structure specified in the
|
|
* <a href="https://docs.bugsnag.com/api/error-reporting/">Error Reporting</a> and
|
|
* <a href="https://docs.bugsnag.com/api/sessions/">Sessions API</a> documentation.
|
|
*
|
|
* You can use the return type from the deliver functions to control the strategy for
|
|
* retrying the transmission at a later date.
|
|
*
|
|
* If DeliveryStatus.UNDELIVERED is returned, the notifier will automatically cache
|
|
* the payload and trigger delivery later on. Otherwise, if either DeliveryStatus.DELIVERED
|
|
* or DeliveryStatus.FAILURE is returned the notifier will removed any cached payload
|
|
* and no further delivery will be attempted.
|
|
*/
|
|
public void setDelivery(@NonNull Delivery delivery) {
|
|
if (delivery != null) {
|
|
impl.setDelivery(delivery);
|
|
} else {
|
|
logNull("delivery");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the endpoints to send data to. By default we'll send error reports to
|
|
* https://notify.bugsnag.com, and sessions to https://sessions.bugsnag.com, but you can
|
|
* override this if you are using Bugsnag Enterprise to point to your own Bugsnag endpoints.
|
|
*/
|
|
@NonNull
|
|
public EndpointConfiguration getEndpoints() {
|
|
return impl.getEndpoints();
|
|
}
|
|
|
|
/**
|
|
* Set the endpoints to send data to. By default we'll send error reports to
|
|
* https://notify.bugsnag.com, and sessions to https://sessions.bugsnag.com, but you can
|
|
* override this if you are using Bugsnag Enterprise to point to your own Bugsnag endpoints.
|
|
*/
|
|
public void setEndpoints(@NonNull EndpointConfiguration endpoints) {
|
|
if (endpoints != null) {
|
|
impl.setEndpoints(endpoints);
|
|
} else {
|
|
logNull("endpoints");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of breadcrumbs which will be stored. Once the threshold is reached,
|
|
* the oldest breadcrumbs will be deleted.
|
|
*
|
|
* By default, 100 breadcrumbs are stored: this can be amended up to a maximum of 500.
|
|
*/
|
|
public int getMaxBreadcrumbs() {
|
|
return impl.getMaxBreadcrumbs();
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of breadcrumbs which will be stored. Once the threshold is reached,
|
|
* the oldest breadcrumbs will be deleted.
|
|
*
|
|
* By default, 100 breadcrumbs are stored: this can be amended up to a maximum of 500.
|
|
*/
|
|
public void setMaxBreadcrumbs(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. "
|
|
+ "Supplied value is " + maxBreadcrumbs);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of persisted events which will be stored. Once the threshold is
|
|
* reached, the oldest event will be deleted.
|
|
*
|
|
* By default, 32 events are persisted.
|
|
*/
|
|
public int getMaxPersistedEvents() {
|
|
return impl.getMaxPersistedEvents();
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of persisted events which will be stored. Once the threshold is
|
|
* reached, the oldest event will be deleted.
|
|
*
|
|
* By default, 32 events are persisted.
|
|
*/
|
|
public void setMaxPersistedEvents(int maxPersistedEvents) {
|
|
if (maxPersistedEvents >= 0) {
|
|
impl.setMaxPersistedEvents(maxPersistedEvents);
|
|
} else {
|
|
getLogger().e("Invalid configuration value detected. "
|
|
+ "Option maxPersistedEvents should be a positive integer."
|
|
+ "Supplied value is " + maxPersistedEvents);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the maximum number of threads that will be reported with an event. Once the threshold is
|
|
* reached, all remaining threads will be omitted.
|
|
*
|
|
* By default, up to 200 threads are reported.
|
|
*/
|
|
public int getMaxReportedThreads() {
|
|
return impl.getMaxReportedThreads();
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of threads that will be reported with an event. Once the threshold is
|
|
* reached, all remaining threads will be omitted.
|
|
*
|
|
* By default, up to 200 threads are reported.
|
|
*/
|
|
public void setMaxReportedThreads(int maxReportedThreads) {
|
|
if (maxReportedThreads >= 0) {
|
|
impl.setMaxReportedThreads(maxReportedThreads);
|
|
} else {
|
|
getLogger().e("Invalid configuration value detected. "
|
|
+ "Option maxReportedThreads should be a positive integer."
|
|
+ "Supplied value is " + maxReportedThreads);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of persisted sessions which will be stored. Once the threshold is
|
|
* reached, the oldest session will be deleted.
|
|
*
|
|
* By default, 128 sessions are persisted.
|
|
*/
|
|
public int getMaxPersistedSessions() {
|
|
return impl.getMaxPersistedSessions();
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum number of persisted sessions which will be stored. Once the threshold is
|
|
* reached, the oldest session will be deleted.
|
|
*
|
|
* By default, 128 sessions are persisted.
|
|
*/
|
|
public void setMaxPersistedSessions(int maxPersistedSessions) {
|
|
if (maxPersistedSessions >= 0) {
|
|
impl.setMaxPersistedSessions(maxPersistedSessions);
|
|
} else {
|
|
getLogger().e("Invalid configuration value detected. "
|
|
+ "Option maxPersistedSessions should be a positive integer."
|
|
+ "Supplied value is " + maxPersistedSessions);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the maximum string length in any metadata field. Once the threshold is
|
|
* reached in a particular string, all excess characters will be deleted.
|
|
*
|
|
* By default, the limit is 10,000.
|
|
*/
|
|
public int getMaxStringValueLength() {
|
|
return impl.getMaxStringValueLength();
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum string length in any metadata field. Once the threshold is
|
|
* reached in a particular string, all excess characters will be deleted.
|
|
*
|
|
* By default, the limit is 10,000.
|
|
*/
|
|
public void setMaxStringValueLength(int maxStringValueLength) {
|
|
if (maxStringValueLength >= 0) {
|
|
impl.setMaxStringValueLength(maxStringValueLength);
|
|
} else {
|
|
getLogger().e("Invalid configuration value detected. "
|
|
+ "Option maxStringValueLength should be a positive integer."
|
|
+ "Supplied value is " + maxStringValueLength);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bugsnag uses the concept of "contexts" to help display and group your errors. Contexts
|
|
* represent what was happening in your application at the time an error occurs.
|
|
*
|
|
* In an android app the "context" is automatically set as the foreground Activity.
|
|
* If you would like to set this value manually, you should alter this property.
|
|
*/
|
|
@Nullable
|
|
public String getContext() {
|
|
return impl.getContext();
|
|
}
|
|
|
|
/**
|
|
* Bugsnag uses the concept of "contexts" to help display and group your errors. Contexts
|
|
* represent what was happening in your application at the time an error occurs.
|
|
*
|
|
* In an android app the "context" is automatically set as the foreground Activity.
|
|
* If you would like to set this value manually, you should alter this property.
|
|
*/
|
|
public void setContext(@Nullable String context) {
|
|
impl.setContext(context);
|
|
}
|
|
|
|
/**
|
|
* Sets which values should be removed from any Metadata objects before
|
|
* sending them to Bugsnag. Use this if you want to ensure you don't send
|
|
* sensitive data such as passwords, and credit card numbers to our
|
|
* servers. Any keys which contain these strings will be filtered.
|
|
*
|
|
* By default, redactedKeys is set to "password"
|
|
*/
|
|
@NonNull
|
|
public Set<String> getRedactedKeys() {
|
|
return impl.getRedactedKeys();
|
|
}
|
|
|
|
/**
|
|
* Sets which values should be removed from any Metadata objects before
|
|
* sending them to Bugsnag. Use this if you want to ensure you don't send
|
|
* sensitive data such as passwords, and credit card numbers to our
|
|
* servers. Any keys which contain these strings will be filtered.
|
|
*
|
|
* By default, redactedKeys is set to "password"
|
|
*/
|
|
public void setRedactedKeys(@NonNull Set<String> redactedKeys) {
|
|
if (CollectionUtils.containsNullElements(redactedKeys)) {
|
|
logNull("redactedKeys");
|
|
} else {
|
|
impl.setRedactedKeys(redactedKeys);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allows you to specify the fully-qualified name of error classes that will be discarded
|
|
* before being sent to Bugsnag if they are detected. The notifier performs an exact
|
|
* match against the canonical class name.
|
|
*/
|
|
@NonNull
|
|
public Set<String> getDiscardClasses() {
|
|
return impl.getDiscardClasses();
|
|
}
|
|
|
|
/**
|
|
* Allows you to specify the fully-qualified name of error classes that will be discarded
|
|
* before being sent to Bugsnag if they are detected. The notifier performs an exact
|
|
* match against the canonical class name.
|
|
*/
|
|
public void setDiscardClasses(@NonNull Set<String> discardClasses) {
|
|
if (CollectionUtils.containsNullElements(discardClasses)) {
|
|
logNull("discardClasses");
|
|
} else {
|
|
impl.setDiscardClasses(discardClasses);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* By default, Bugsnag will be notified of events that happen in any releaseStage.
|
|
* If you would like to change which release stages notify Bugsnag you can set this property.
|
|
*/
|
|
@Nullable
|
|
public Set<String> getEnabledReleaseStages() {
|
|
return impl.getEnabledReleaseStages();
|
|
}
|
|
|
|
/**
|
|
* By default, Bugsnag will be notified of events that happen in any releaseStage.
|
|
* If you would like to change which release stages notify Bugsnag you can set this property.
|
|
*/
|
|
public void setEnabledReleaseStages(@Nullable Set<String> enabledReleaseStages) {
|
|
impl.setEnabledReleaseStages(enabledReleaseStages);
|
|
}
|
|
|
|
/**
|
|
* By default we will automatically add breadcrumbs for common application events such as
|
|
* activity lifecycle events and system intents. To amend this behavior,
|
|
* override the enabled breadcrumb types. All breadcrumbs can be disabled by providing an
|
|
* empty set.
|
|
*
|
|
* The following breadcrumb types can be enabled:
|
|
*
|
|
* - Captured errors: left when an error event is sent to the Bugsnag API.
|
|
* - Manual breadcrumbs: left via the Bugsnag.leaveBreadcrumb function.
|
|
* - Navigation changes: left for Activity Lifecycle events to track the user's journey in
|
|
* the app.
|
|
* - State changes: state breadcrumbs are left for system broadcast events. For example:
|
|
* battery warnings, airplane mode, etc.
|
|
* - User interaction: left when the user performs certain system operations.
|
|
*/
|
|
@Nullable
|
|
public Set<BreadcrumbType> getEnabledBreadcrumbTypes() {
|
|
return impl.getEnabledBreadcrumbTypes();
|
|
}
|
|
|
|
/**
|
|
* By default we will automatically add breadcrumbs for common application events such as
|
|
* activity lifecycle events and system intents. To amend this behavior,
|
|
* override the enabled breadcrumb types. All breadcrumbs can be disabled by providing an
|
|
* empty set.
|
|
*
|
|
* The following breadcrumb types can be enabled:
|
|
*
|
|
* - Captured errors: left when an error event is sent to the Bugsnag API.
|
|
* - Manual breadcrumbs: left via the Bugsnag.leaveBreadcrumb function.
|
|
* - Navigation changes: left for Activity Lifecycle events to track the user's journey in
|
|
* the app.
|
|
* - State changes: state breadcrumbs are left for system broadcast events. For example:
|
|
* battery warnings, airplane mode, etc.
|
|
* - User interaction: left when the user performs certain system operations.
|
|
*/
|
|
public void setEnabledBreadcrumbTypes(@Nullable Set<BreadcrumbType> enabledBreadcrumbTypes) {
|
|
impl.setEnabledBreadcrumbTypes(enabledBreadcrumbTypes);
|
|
}
|
|
|
|
@NonNull
|
|
public Set<Telemetry> getTelemetry() {
|
|
return impl.getTelemetry();
|
|
}
|
|
|
|
/**
|
|
* Set which telemetry will be sent to Bugsnag. By default, all telemetry is enabled.
|
|
*
|
|
* The following telemetry can be enabled:
|
|
*
|
|
* - internal errors: Errors in the Bugsnag SDK itself.
|
|
*/
|
|
public void setTelemetry(@NonNull Set<Telemetry> telemetry) {
|
|
if (telemetry != null) {
|
|
impl.setTelemetry(telemetry);
|
|
} else {
|
|
logNull("telemetry");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets which package names Bugsnag should consider as a part of the
|
|
* running application. We mark stacktrace lines as in-project if they
|
|
* originate from any of these packages and this allows us to improve
|
|
* the visual display of the stacktrace on the dashboard.
|
|
*
|
|
* By default, projectPackages is set to be the package you called Bugsnag.start from.
|
|
*/
|
|
@NonNull
|
|
public Set<String> getProjectPackages() {
|
|
return impl.getProjectPackages();
|
|
}
|
|
|
|
/**
|
|
* Sets which package names Bugsnag should consider as a part of the
|
|
* running application. We mark stacktrace lines as in-project if they
|
|
* originate from any of these packages and this allows us to improve
|
|
* the visual display of the stacktrace on the dashboard.
|
|
*
|
|
* By default, projectPackages is set to be the package you called Bugsnag.start from.
|
|
*/
|
|
public void setProjectPackages(@NonNull Set<String> projectPackages) {
|
|
if (CollectionUtils.containsNullElements(projectPackages)) {
|
|
logNull("projectPackages");
|
|
} else {
|
|
impl.setProjectPackages(projectPackages);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a "on error" callback, to execute code at the point where an error report is
|
|
* captured in Bugsnag.
|
|
*
|
|
* You can use this to add or modify information attached to an Event
|
|
* before it is sent to your dashboard. You can also return
|
|
* <code>false</code> from any callback to prevent delivery. "on error"
|
|
* callbacks do not run before reports generated in the event
|
|
* of immediate app termination from crashes in C/C++ code.
|
|
*
|
|
* For example:
|
|
*
|
|
* Bugsnag.addOnError(new OnErrorCallback() {
|
|
* public boolean run(Event event) {
|
|
* event.setSeverity(Severity.INFO);
|
|
* return true;
|
|
* }
|
|
* })
|
|
*
|
|
* @param onError a callback to run before sending errors to Bugsnag
|
|
* @see OnErrorCallback
|
|
*/
|
|
@Override
|
|
public void addOnError(@NonNull OnErrorCallback onError) {
|
|
if (onError != null) {
|
|
impl.addOnError(onError);
|
|
} else {
|
|
logNull("addOnError");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes a previously added "on error" callback
|
|
* @param onError the callback to remove
|
|
*/
|
|
@Override
|
|
public void removeOnError(@NonNull OnErrorCallback onError) {
|
|
if (onError != null) {
|
|
impl.removeOnError(onError);
|
|
} else {
|
|
logNull("removeOnError");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add an "on breadcrumb" callback, to execute code before every
|
|
* breadcrumb captured by Bugsnag.
|
|
*
|
|
* You can use this to modify breadcrumbs before they are stored by Bugsnag.
|
|
* You can also return <code>false</code> from any callback to ignore a breadcrumb.
|
|
*
|
|
* For example:
|
|
*
|
|
* Bugsnag.onBreadcrumb(new OnBreadcrumbCallback() {
|
|
* public boolean run(Breadcrumb breadcrumb) {
|
|
* return false; // ignore the breadcrumb
|
|
* }
|
|
* })
|
|
*
|
|
* @param onBreadcrumb a callback to run before a breadcrumb is captured
|
|
* @see OnBreadcrumbCallback
|
|
*/
|
|
@Override
|
|
public void addOnBreadcrumb(@NonNull OnBreadcrumbCallback onBreadcrumb) {
|
|
if (onBreadcrumb != null) {
|
|
impl.addOnBreadcrumb(onBreadcrumb);
|
|
} else {
|
|
logNull("addOnBreadcrumb");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes a previously added "on breadcrumb" callback
|
|
* @param onBreadcrumb the callback to remove
|
|
*/
|
|
@Override
|
|
public void removeOnBreadcrumb(@NonNull OnBreadcrumbCallback onBreadcrumb) {
|
|
if (onBreadcrumb != null) {
|
|
impl.removeOnBreadcrumb(onBreadcrumb);
|
|
} else {
|
|
logNull("removeOnBreadcrumb");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add an "on session" callback, to execute code before every
|
|
* session captured by Bugsnag.
|
|
*
|
|
* You can use this to modify sessions before they are stored by Bugsnag.
|
|
* You can also return <code>false</code> from any callback to ignore a session.
|
|
*
|
|
* For example:
|
|
*
|
|
* Bugsnag.onSession(new OnSessionCallback() {
|
|
* public boolean run(Session session) {
|
|
* return false; // ignore the session
|
|
* }
|
|
* })
|
|
*
|
|
* @param onSession a callback to run before a session is captured
|
|
* @see OnSessionCallback
|
|
*/
|
|
@Override
|
|
public void addOnSession(@NonNull OnSessionCallback onSession) {
|
|
if (onSession != null) {
|
|
impl.addOnSession(onSession);
|
|
} else {
|
|
logNull("addOnSession");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes a previously added "on session" callback
|
|
* @param onSession the callback to remove
|
|
*/
|
|
@Override
|
|
public void removeOnSession(@NonNull OnSessionCallback onSession) {
|
|
if (onSession != null) {
|
|
impl.removeOnSession(onSession);
|
|
} else {
|
|
logNull("removeOnSession");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a callback which will be invoked prior to an event being delivered
|
|
* to Bugsnag. The callback can be used to modify events or cancel
|
|
* delivering the event altogether by returning <code>false</code>. Note
|
|
* that the callback may be invoked in the current or a subsequent app
|
|
* launch depending on whether the app terminated prior to delivering the
|
|
* event.
|
|
*
|
|
* @param onSend the callback to add
|
|
* @see OnSendCallback
|
|
*/
|
|
public void addOnSend(@NonNull OnSendCallback onSend) {
|
|
if (onSend != null) {
|
|
impl.addOnSend(onSend);
|
|
} else {
|
|
logNull("addOnSend");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a callback previously added with {@link Configuration#addOnSend(OnSendCallback)}
|
|
*
|
|
* @param onSend the callback to remove
|
|
*/
|
|
public void removeOnSend(@NonNull OnSendCallback onSend) {
|
|
if (onSend != null) {
|
|
impl.removeOnSend(onSend);
|
|
} else {
|
|
logNull("removeOnSend");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a map of multiple metadata key-value pairs to the specified section.
|
|
*/
|
|
@Override
|
|
public void addMetadata(@NonNull String section, @NonNull Map<String, ?> value) {
|
|
if (section != null && value != null) {
|
|
impl.addMetadata(section, value);
|
|
} else {
|
|
logNull("addMetadata");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds the specified key and value in the specified section. The value can be of
|
|
* any primitive type or a collection such as a map, set or array.
|
|
*/
|
|
@Override
|
|
public void addMetadata(@NonNull String section, @NonNull String key, @Nullable Object value) {
|
|
if (section != null && key != null) {
|
|
impl.addMetadata(section, key, value);
|
|
} else {
|
|
logNull("addMetadata");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all the data from the specified section.
|
|
*/
|
|
@Override
|
|
public void clearMetadata(@NonNull String section) {
|
|
if (section != null) {
|
|
impl.clearMetadata(section);
|
|
} else {
|
|
logNull("clearMetadata");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes data with the specified key from the specified section.
|
|
*/
|
|
@Override
|
|
public void clearMetadata(@NonNull String section, @NonNull String key) {
|
|
if (section != null && key != null) {
|
|
impl.clearMetadata(section, key);
|
|
} else {
|
|
logNull("clearMetadata");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a map of data in the specified section.
|
|
*/
|
|
@Nullable
|
|
@Override
|
|
public Map<String, Object> getMetadata(@NonNull String section) {
|
|
if (section != null) {
|
|
return impl.getMetadata(section);
|
|
} else {
|
|
logNull("getMetadata");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the specified key in the specified section.
|
|
*/
|
|
@Nullable
|
|
@Override
|
|
public Object getMetadata(@NonNull String section, @NonNull String key) {
|
|
if (section != null && key != null) {
|
|
return impl.getMetadata(section, key);
|
|
} else {
|
|
logNull("getMetadata");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void addFeatureFlag(@NonNull String name) {
|
|
if (name != null) {
|
|
impl.addFeatureFlag(name);
|
|
} else {
|
|
logNull("addFeatureFlag");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void addFeatureFlag(@NonNull String name, @Nullable String variant) {
|
|
if (name != null) {
|
|
impl.addFeatureFlag(name, variant);
|
|
} else {
|
|
logNull("addFeatureFlag");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void addFeatureFlags(@NonNull Iterable<FeatureFlag> featureFlags) {
|
|
if (featureFlags != null) {
|
|
impl.addFeatureFlags(featureFlags);
|
|
} else {
|
|
logNull("addFeatureFlags");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void clearFeatureFlag(@NonNull String name) {
|
|
if (name != null) {
|
|
impl.clearFeatureFlag(name);
|
|
} else {
|
|
logNull("clearFeatureFlag");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void clearFeatureFlags() {
|
|
impl.clearFeatureFlags();
|
|
}
|
|
|
|
/**
|
|
* Returns the currently set User information.
|
|
*/
|
|
@NonNull
|
|
@Override
|
|
public User getUser() {
|
|
return impl.getUser();
|
|
}
|
|
|
|
/**
|
|
* Sets the user associated with the event.
|
|
*/
|
|
@Override
|
|
public void setUser(@Nullable String id, @Nullable String email, @Nullable String name) {
|
|
impl.setUser(id, email, name);
|
|
}
|
|
|
|
/**
|
|
* Adds a plugin which will be loaded when the bugsnag notifier is instantiated.
|
|
*/
|
|
public void addPlugin(@NonNull Plugin plugin) {
|
|
if (plugin != null) {
|
|
impl.addPlugin(plugin);
|
|
} else {
|
|
logNull("addPlugin");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Whether Bugsnag should try to send crashing errors prior to app termination.
|
|
*
|
|
* Delivery will only be attempted for uncaught Java / Kotlin exceptions or errors, and
|
|
* while in progress will block the crashing thread for up to 3 seconds.
|
|
*
|
|
* Delivery on crash should be considered unreliable due to the necessary short timeout and
|
|
* potential for generating "errors on errors".
|
|
*
|
|
* Use of this feature is discouraged because it:
|
|
* - may cause Application Not Responding (ANR) errors on-top of existing crashes
|
|
* - will result in duplicate errors in your Dashboard when errors are not detected as sent
|
|
* before termination
|
|
* - may prevent other error handlers from detecting or reporting a crash
|
|
*
|
|
* By default this value is {@code false}.
|
|
*
|
|
* @param attemptDeliveryOnCrash {@code true} if Bugsnag should try to send crashing errors
|
|
* prior to app termination
|
|
*/
|
|
public void setAttemptDeliveryOnCrash(boolean attemptDeliveryOnCrash) {
|
|
impl.setAttemptDeliveryOnCrash(attemptDeliveryOnCrash);
|
|
}
|
|
|
|
/**
|
|
* Whether Bugsnag should try to send crashing errors prior to app termination.
|
|
*
|
|
* @see #setAttemptDeliveryOnCrash(boolean)
|
|
*/
|
|
public boolean isAttemptDeliveryOnCrash() {
|
|
return impl.getAttemptDeliveryOnCrash();
|
|
}
|
|
|
|
Set<Plugin> getPlugins() {
|
|
return impl.getPlugins();
|
|
}
|
|
|
|
Notifier getNotifier() {
|
|
return impl.getNotifier();
|
|
}
|
|
}
|