misc fixes and upgrades
Signed-off-by: androidacy-user <opensource@androidacy.com>pull/89/head
parent
c4ea88c927
commit
6d22c3c885
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
||||
*/
|
||||
|
||||
package com.fox2code.mmm.utils.sentry
|
||||
|
||||
import io.sentry.Breadcrumb
|
||||
import io.sentry.SentryLevel
|
||||
import java.util.Objects
|
||||
|
||||
class SentryBreadcrumb {
|
||||
val breadcrumb: Breadcrumb = Breadcrumb()
|
||||
|
||||
init {
|
||||
breadcrumb.level = SentryLevel.INFO
|
||||
}
|
||||
|
||||
fun setType(type: String?) {
|
||||
breadcrumb.type = type
|
||||
}
|
||||
|
||||
fun setData(key: String, value: Any?) {
|
||||
@Suppress("NAME_SHADOWING") var value = value
|
||||
if (value == null) value = "null"
|
||||
Objects.requireNonNull(key)
|
||||
breadcrumb.setData(key, value)
|
||||
}
|
||||
|
||||
fun setCategory(category: String?) {
|
||||
breadcrumb.category = category
|
||||
}
|
||||
}
|
||||
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
|
||||
*/
|
||||
|
||||
package com.fox2code.mmm.utils.sentry
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Process
|
||||
import com.fox2code.mmm.BuildConfig
|
||||
import com.fox2code.mmm.CrashHandler
|
||||
import com.fox2code.mmm.MainApplication
|
||||
import com.fox2code.mmm.androidacy.AndroidacyUtil.Companion.hideToken
|
||||
import com.fox2code.mmm.androidacy.AndroidacyUtil.Companion.isAndroidacyLink
|
||||
import com.fox2code.mmm.utils.io.net.HttpException
|
||||
import io.sentry.Breadcrumb
|
||||
import io.sentry.Hint
|
||||
import io.sentry.Sentry
|
||||
import io.sentry.SentryEvent
|
||||
import io.sentry.SentryLevel
|
||||
import io.sentry.SentryOptions.BeforeBreadcrumbCallback
|
||||
import io.sentry.SentryOptions.BeforeSendCallback
|
||||
import io.sentry.android.core.SentryAndroid
|
||||
import io.sentry.android.core.SentryAndroidOptions
|
||||
import io.sentry.android.fragment.FragmentLifecycleIntegration
|
||||
import io.sentry.android.timber.SentryTimberIntegration
|
||||
import io.sentry.protocol.SentryId
|
||||
import org.matomo.sdk.extra.TrackHelper
|
||||
import timber.log.Timber
|
||||
|
||||
object SentryMain {
|
||||
const val IS_SENTRY_INSTALLED = true
|
||||
private var isCrashing = false
|
||||
private var isSentryEnabled = false
|
||||
private var crashExceptionId: SentryId? = null
|
||||
|
||||
/**
|
||||
* Initialize Sentry
|
||||
* Sentry is used for crash reporting and performance monitoring.
|
||||
*/
|
||||
@JvmStatic
|
||||
@SuppressLint("RestrictedApi", "UnspecifiedImmutableFlag", "ApplySharedPref")
|
||||
fun initialize(mainApplication: MainApplication) {
|
||||
Thread.setDefaultUncaughtExceptionHandler { _: Thread?, throwable: Throwable ->
|
||||
isCrashing = true
|
||||
MainApplication.clearCachedSharedPrefs()
|
||||
TrackHelper.track().exception(throwable).with(MainApplication.INSTANCE!!.tracker)
|
||||
// open crash handler and exit
|
||||
val intent = Intent(mainApplication, CrashHandler::class.java)
|
||||
// pass the entire exception to the crash handler
|
||||
intent.putExtra("exception", throwable)
|
||||
// add stacktrace as string
|
||||
intent.putExtra("stacktrace", throwable.stackTrace)
|
||||
// serialize Sentry.captureException and pass it to the crash handler
|
||||
intent.putExtra("sentryException", throwable)
|
||||
// pass crashReportingEnabled to crash handler
|
||||
intent.putExtra("crashReportingEnabled", isSentryEnabled)
|
||||
// add isCrashing to intent
|
||||
intent.putExtra("isCrashing", true)
|
||||
// add crashExceptionId to intent
|
||||
if (crashExceptionId != null) {
|
||||
intent.putExtra("lastEventId", crashExceptionId!!.toString())
|
||||
} else {
|
||||
intent.putExtra("lastEventId", "")
|
||||
}
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
Timber.e("Starting crash handler")
|
||||
mainApplication.startActivity(intent)
|
||||
Timber.e("Exiting")
|
||||
Process.killProcess(Process.myPid())
|
||||
}
|
||||
// If first_launch pref is not false, refuse to initialize Sentry
|
||||
val sharedPreferences = MainApplication.getSharedPreferences("mmm")!!
|
||||
if (sharedPreferences.getString("last_shown_setup", null) != "v4") {
|
||||
return
|
||||
}
|
||||
isSentryEnabled = sharedPreferences.getBoolean("pref_crash_reporting_enabled", false)
|
||||
// set sentryEnabled on preference change of pref_crash_reporting_enabled
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener { sharedPreferences1: SharedPreferences, s: String? ->
|
||||
if (s !== null && s == "pref_crash_reporting_enabled") {
|
||||
isSentryEnabled = sharedPreferences1.getBoolean(s, false)
|
||||
}
|
||||
}
|
||||
SentryAndroid.init(mainApplication) { options: SentryAndroidOptions ->
|
||||
// If crash reporting is disabled, stop here.
|
||||
if (!MainApplication.isCrashReportingEnabled) {
|
||||
isSentryEnabled = false // Set sentry state to disabled
|
||||
options.dsn = ""
|
||||
} else {
|
||||
// get pref_crash_reporting_pii pref
|
||||
val crashReportingPii = sharedPreferences.getBoolean("crashReportingPii", false)
|
||||
isSentryEnabled = true // Set sentry state to enabled
|
||||
options.addIntegration(
|
||||
FragmentLifecycleIntegration(
|
||||
mainApplication,
|
||||
enableFragmentLifecycleBreadcrumbs = true,
|
||||
enableAutoFragmentLifecycleTracing = true
|
||||
)
|
||||
)
|
||||
// Enable automatic activity lifecycle breadcrumbs
|
||||
options.isEnableActivityLifecycleBreadcrumbs = true
|
||||
// Enable automatic fragment lifecycle breadcrumbs
|
||||
options.addIntegration(SentryTimberIntegration())
|
||||
options.isCollectAdditionalContext = true
|
||||
options.isAttachThreads = true
|
||||
options.isAttachStacktrace = true
|
||||
options.isEnableNdk = true
|
||||
options.addInAppInclude("com.fox2code.mmm")
|
||||
options.addInAppInclude("com.fox2code.mmm.debug")
|
||||
options.addInAppInclude("com.fox2code.mmm.fdroid")
|
||||
options.addInAppExclude("com.fox2code.mmm.utils.sentry.SentryMain")
|
||||
options.addInAppInclude("com.fox2code.mmm.utils")
|
||||
// Respect user preference for sending PII. default is true on non fdroid builds, false on fdroid builds
|
||||
options.isSendDefaultPii = crashReportingPii
|
||||
options.enableAllAutoBreadcrumbs(true)
|
||||
// in-app screenshots are only sent if the app crashes, and it only shows the last activity. so no, we won't see your, ahem, "private" stuff
|
||||
options.isAttachScreenshot = true
|
||||
// It just tell if sentry should ping the sentry dsn to tell the app is running. Useful for performance and profiling.
|
||||
options.isEnableAutoSessionTracking = true
|
||||
// disable crash tracking - we handle that ourselves
|
||||
options.isEnableUncaughtExceptionHandler = true
|
||||
// Add a callback that will be used before the event is sent to Sentry.
|
||||
// With this callback, you can modify the event or, when returning null, also discard the event.
|
||||
options.environment = BuildConfig.BUILD_TYPE
|
||||
options.beforeSend = BeforeSendCallback { event: SentryEvent?, _: Hint? ->
|
||||
// in the rare event that crash reporting has been disabled since we started the app, we don't want to send the crash report
|
||||
if (!isSentryEnabled) {
|
||||
return@BeforeSendCallback null
|
||||
}
|
||||
crashExceptionId = event?.eventId
|
||||
// if debug build, log everything, but for release only log errors
|
||||
if (!BuildConfig.DEBUG) {
|
||||
if (event?.level == SentryLevel.DEBUG || event?.level == SentryLevel.INFO || event?.level == SentryLevel.WARNING) {
|
||||
return@BeforeSendCallback null
|
||||
}
|
||||
}
|
||||
// remove all failed to fetch data messages
|
||||
if (event?.message?.message?.contains("Failed to fetch") == true || event?.message?.message?.contains(
|
||||
"Failed to load"
|
||||
) == true
|
||||
) {
|
||||
return@BeforeSendCallback null
|
||||
}
|
||||
// for httpexception, do not send if error is 401, 403, 404, 429
|
||||
// get exception from event
|
||||
val exception = event?.throwable ?: return@BeforeSendCallback event
|
||||
// check status code
|
||||
if (exception is HttpException) {
|
||||
if (exception.errorCode in intArrayOf(401, 403, 404, 429)) {
|
||||
return@BeforeSendCallback null
|
||||
}
|
||||
}
|
||||
// if exception is null, return event
|
||||
event
|
||||
}
|
||||
// Filter breadcrumb content from crash report.
|
||||
options.beforeBreadcrumb =
|
||||
BeforeBreadcrumbCallback { breadcrumb: Breadcrumb, _: Hint? ->
|
||||
if (!isSentryEnabled) {
|
||||
return@BeforeBreadcrumbCallback null
|
||||
}
|
||||
val url = breadcrumb.getData("url") as String?
|
||||
if ("cloudflare-dns.com" == Uri.parse(url).host) {
|
||||
return@BeforeBreadcrumbCallback null
|
||||
}
|
||||
if (isAndroidacyLink(url)) {
|
||||
url?.let { hideToken(it) }?.let { breadcrumb.setData("url", it) }
|
||||
}
|
||||
breadcrumb
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addSentryBreadcrumb(sentryBreadcrumb: SentryBreadcrumb) {
|
||||
if (MainApplication.isCrashReportingEnabled) {
|
||||
Sentry.addBreadcrumb(sentryBreadcrumb.breadcrumb)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,30 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<PreferenceCategory app:title="@string/pref_category_contributors">
|
||||
<!-- Small lil thanks to Androidacy -->
|
||||
<com.fox2code.mmm.settings.LongClickablePreference
|
||||
app:icon="@drawable/baseline_favorite_24"
|
||||
app:icon="@drawable/ic_baseline_android_24"
|
||||
app:key="pref_androidacy_thanks"
|
||||
app:singleLineTitle="false"
|
||||
app:summary="@string/androidacy_thanks_desc"
|
||||
app:title="@string/androidacy_thanks" />
|
||||
app:summary="@string/androidacy_thanks_desc_v2"
|
||||
app:title="@string/androidacy_thanks_v2" />
|
||||
<!-- Small lil thanks to Fox2Code -->
|
||||
<com.fox2code.mmm.settings.LongClickablePreference
|
||||
app:icon="@drawable/baseline_favorite_24"
|
||||
app:key="pref_fox2code_thanks"
|
||||
app:singleLineTitle="false"
|
||||
app:summary="@string/fox2code_thanks_desc"
|
||||
app:title="@string/fox2code_thanks" />
|
||||
app:summary="@string/fox2code_thanks_desc_v2"
|
||||
app:title="@string/fox2code_thanks_v2" />
|
||||
<!-- OKay, so we'll thank all the other contributors too -->
|
||||
<com.fox2code.mmm.settings.LongClickablePreference
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="pref_contributors"
|
||||
app:singleLineTitle="false"
|
||||
app:title="@string/contributors" />
|
||||
app:summary="@string/contributors" />
|
||||
<!-- And the translators -->
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue