1- package com.fox2code.mmm.utils.sentry ;
1+ package com.fox2code.mmm.utils.sentry
22
3- import android.annotation.SuppressLint;
4- import android.content.Context;
5- import android.content.Intent;
6- import android.content.SharedPreferences;
7- import android.net.Uri;
3+ import android.annotation.SuppressLint
4+ import android.content.Context
5+ import android.content.Intent
6+ import android.content.SharedPreferences
7+ import android.net.Uri
8+ import android.os.Process
9+ import com.fox2code.mmm.CrashHandler
10+ import com.fox2code.mmm.MainApplication
11+ import com.fox2code.mmm.androidacy.AndroidacyUtil.Companion.hideToken
12+ import com.fox2code.mmm.androidacy.AndroidacyUtil.Companion.isAndroidacyLink
13+ import io.sentry.Breadcrumb
14+ import io.sentry.Hint
15+ import io.sentry.Sentry
16+ import io.sentry.SentryEvent
17+ import io.sentry.SentryOptions.BeforeBreadcrumbCallback
18+ import io.sentry.SentryOptions.BeforeSendCallback
19+ import io.sentry.android.core.SentryAndroid
20+ import io.sentry.android.core.SentryAndroidOptions
21+ import io.sentry.android.fragment.FragmentLifecycleIntegration
22+ import io.sentry.android.timber.SentryTimberIntegration
23+ import org.matomo.sdk.extra.TrackHelper
24+ import timber.log.Timber
825
9- import com.fox2code.mmm.CrashHandler;
10- import com.fox2code.mmm.MainApplication;
11- import com.fox2code.mmm.androidacy.AndroidacyUtil;
12-
13- import org.matomo.sdk.extra.TrackHelper;
14-
15- import java.util.Objects;
16-
17- import io.sentry.Sentry;
18- import io.sentry.android.core.SentryAndroid;
19- import io.sentry.android.fragment.FragmentLifecycleIntegration;
20- import io.sentry.android.timber.SentryTimberIntegration;
21- import timber.log.Timber;
22-
23- public class SentryMain {
24- public static final boolean IS_SENTRY_INSTALLED = true ;
25- public static boolean isCrashing = false ;
26- private static boolean sentryEnabled = false ;
26+ object SentryMain {
27+ const val IS_SENTRY_INSTALLED = true
28+ private var isCrashing = false
29+ private var isSentryEnabled = false
2730
2831 /* *
2932 * Initialize Sentry
3033 * Sentry is used for crash reporting and performance monitoring.
3134 */
32- @SuppressLint({" RestrictedApi" , " UnspecifiedImmutableFlag" })
33- public static void initialize(final MainApplication mainApplication) {
34- Thread .setDefaultUncaughtExceptionHandler((thread, throwable) -> {
35- isCrashing = true ;
36- TrackHelper .track().exception(throwable).with (MainApplication .getINSTANCE().getTracker());
37- SharedPreferences .Editor editor = MainApplication .getINSTANCE().getSharedPreferences(" sentry" , Context .MODE_PRIVATE ).edit();
38- editor.putString(" lastExitReason" , " crash" );
39- editor.putLong(" lastExitTime" , System .currentTimeMillis());
40- editor.putString(" lastExitReason" , " crash" );
41- editor.putString(" lastExitId" , String .valueOf(Sentry .getLastEventId()));
42- editor.apply ();
43- Timber .e(" Uncaught exception with sentry ID %s and stacktrace %s" , Sentry .getLastEventId(), throwable.getStackTrace());
35+ @JvmStatic
36+ @SuppressLint(" RestrictedApi" , " UnspecifiedImmutableFlag" )
37+ fun initialize (mainApplication : MainApplication ) {
38+ Thread .setDefaultUncaughtExceptionHandler { _: Thread ? , throwable: Throwable ->
39+ isCrashing = true
40+ TrackHelper .track().exception(throwable).with (MainApplication .getINSTANCE().tracker)
41+ val editor =
42+ MainApplication .getINSTANCE().getSharedPreferences(" sentry" , Context .MODE_PRIVATE )
43+ .edit()
44+ editor.putString(" lastExitReason" , " crash" )
45+ editor.putLong(" lastExitTime" , System .currentTimeMillis())
46+ editor.putString(" lastExitReason" , " crash" )
47+ editor.putString(" lastExitId" , Sentry .getLastEventId().toString())
48+ editor.apply ()
49+ Timber .e(
50+ " Uncaught exception with sentry ID %s and stacktrace %s" ,
51+ Sentry .getLastEventId(),
52+ throwable.stackTrace
53+ )
4454 // open crash handler and exit
45- Intent intent = new Intent (mainApplication, CrashHandler . class );
55+ val intent = Intent (mainApplication, CrashHandler :: class .java)
4656 // pass the entire exception to the crash handler
47- intent.putExtra(" exception" , throwable);
57+ intent.putExtra(" exception" , throwable)
4858 // add stacktrace as string
49- intent.putExtra(" stacktrace" , throwable.getStackTrace());
59+ intent.putExtra(" stacktrace" , throwable.stackTrace)
5060 // put lastEventId in intent (get from preferences)
51- intent.putExtra(" lastEventId" , String .valueOf( Sentry .getLastEventId()));
61+ intent.putExtra(" lastEventId" , Sentry .getLastEventId().toString())
5262 // serialize Sentry.captureException and pass it to the crash handler
53- intent.putExtra(" sentryException" , throwable);
63+ intent.putExtra(" sentryException" , throwable)
5464 // pass crashReportingEnabled to crash handler
55- intent.putExtra(" crashReportingEnabled" , isSentryEnabled());
65+ intent.putExtra(" crashReportingEnabled" , isSentryEnabled)
5666 // add isCrashing to intent
57- intent.putExtra(" isCrashing" , isCrashing);
58- intent.addFlags(Intent .FLAG_ACTIVITY_NEW_TASK | Intent .FLAG_ACTIVITY_CLEAR_TASK );
59- Timber .e(" Starting crash handler" );
60- mainApplication.startActivity(intent);
61- Timber .e(" Exiting" );
62- android.os. Process .killProcess(android.os. Process .myPid());
63- });
67+ intent.putExtra(" isCrashing" , isCrashing)
68+ intent.addFlags(Intent .FLAG_ACTIVITY_NEW_TASK or Intent .FLAG_ACTIVITY_CLEAR_TASK )
69+ Timber .e(" Starting crash handler" )
70+ mainApplication.startActivity(intent)
71+ Timber .e(" Exiting" )
72+ Process .killProcess(Process .myPid())
73+ }
6474 // If first_launch pref is not false, refuse to initialize Sentry
65- SharedPreferences sharedPreferences = MainApplication .getSharedPreferences(" mmm" );
66- if (! Objects .equals( sharedPreferences.getString(" last_shown_setup" , null ), " v2" ) ) {
67- return ;
75+ val sharedPreferences = MainApplication .getSharedPreferences(" mmm" )
76+ if (sharedPreferences.getString(" last_shown_setup" , null ) != " v2" ) {
77+ return
6878 }
69- sentryEnabled = sharedPreferences.getBoolean(" pref_crash_reporting_enabled" , false );
79+ isSentryEnabled = sharedPreferences.getBoolean(" pref_crash_reporting_enabled" , false )
7080 // set sentryEnabled on preference change of pref_crash_reporting_enabled
71- sharedPreferences.registerOnSharedPreferenceChangeListener(( sharedPreferences1, s) -> {
72- if (s.equals( " pref_crash_reporting_enabled" ) ) {
73- sentryEnabled = sharedPreferences1.getBoolean(s, false );
81+ sharedPreferences.registerOnSharedPreferenceChangeListener { sharedPreferences1: SharedPreferences , s: String ->
82+ if (s == " pref_crash_reporting_enabled" ) {
83+ isSentryEnabled = sharedPreferences1.getBoolean(s, false )
7484 }
75- });
76- SentryAndroid .init (mainApplication, options -> {
85+ }
86+ SentryAndroid .init (mainApplication) { options: SentryAndroidOptions ->
7787 // If crash reporting is disabled, stop here.
7888 if (! MainApplication .isCrashReportingEnabled()) {
79- sentryEnabled = false ; // Set sentry state to disabled
80- options.setDsn( " " );
89+ isSentryEnabled = false // Set sentry state to disabled
90+ options.dsn = " "
8191 } else {
8292 // get pref_crash_reporting_pii pref
83- boolean crashReportingPii = sharedPreferences.getBoolean(" crashReportingPii" , false );
84- sentryEnabled = true ; // Set sentry state to enabled
85- options.addIntegration(new FragmentLifecycleIntegration (mainApplication, true , true ));
93+ val crashReportingPii = sharedPreferences.getBoolean(" crashReportingPii" , false )
94+ isSentryEnabled = true // Set sentry state to enabled
95+ options.addIntegration(FragmentLifecycleIntegration (mainApplication,
96+ enableFragmentLifecycleBreadcrumbs = true ,
97+ enableAutoFragmentLifecycleTracing = true
98+ ))
8699 // Enable automatic activity lifecycle breadcrumbs
87- options.setEnableActivityLifecycleBreadcrumbs( true );
100+ options.isEnableActivityLifecycleBreadcrumbs = true
88101 // Enable automatic fragment lifecycle breadcrumbs
89- options.addIntegration(new SentryTimberIntegration ());
90- options.setCollectAdditionalContext( true );
91- options.setAttachThreads( true );
92- options.setAttachStacktrace( true );
93- options.setEnableNdk( true );
94- options.addInAppInclude(" com.fox2code.mmm" );
95- options.addInAppInclude(" com.fox2code.mmm.debug" );
96- options.addInAppInclude(" com.fox2code.mmm.fdroid" );
97- options.addInAppExclude(" com.fox2code.mmm.utils.sentry.SentryMain" );
102+ options.addIntegration(SentryTimberIntegration ())
103+ options.isCollectAdditionalContext = true
104+ options.isAttachThreads = true
105+ options.isAttachStacktrace = true
106+ options.isEnableNdk = true
107+ options.addInAppInclude(" com.fox2code.mmm" )
108+ options.addInAppInclude(" com.fox2code.mmm.debug" )
109+ options.addInAppInclude(" com.fox2code.mmm.fdroid" )
110+ options.addInAppExclude(" com.fox2code.mmm.utils.sentry.SentryMain" )
98111 // Respect user preference for sending PII. default is true on non fdroid builds, false on fdroid builds
99- options.setSendDefaultPii( crashReportingPii);
100- options.enableAllAutoBreadcrumbs(true );
112+ options.isSendDefaultPii = crashReportingPii
113+ options.enableAllAutoBreadcrumbs(true )
101114 // 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
102- options.setAttachScreenshot( true );
115+ options.isAttachScreenshot = true
103116 // It just tell if sentry should ping the sentry dsn to tell the app is running. Useful for performance and profiling.
104- options.setEnableAutoSessionTracking( true );
117+ options.isEnableAutoSessionTracking = true
105118 // disable crash tracking - we handle that ourselves
106- options.setEnableUncaughtExceptionHandler( false );
119+ options.isEnableUncaughtExceptionHandler = false
107120 // Add a callback that will be used before the event is sent to Sentry.
108121 // With this callback, you can modify the event or, when returning null, also discard the event.
109- options.setBeforeSend(( event, hint) -> {
122+ options.beforeSend = BeforeSendCallback { event: SentryEvent ? , _ : Hint ? ->
110123 // in the rare event that crash reporting has been disabled since we started the app, we don't want to send the crash report
111- if (! sentryEnabled) {
112- return null ;
113- }
114- if (isCrashing) {
115- return null ;
124+ if (! isSentryEnabled || isCrashing) {
125+ return @BeforeSendCallback null
116126 }
117- return event;
118- });
127+ event
128+ }
119129 // Filter breadcrumb content from crash report.
120- options.setBeforeBreadcrumb((breadcrumb, hint) -> {
121- String url = (String ) breadcrumb.getData(" url" );
122- if (url == null || url.isEmpty()) return breadcrumb;
123- if (" cloudflare-dns.com" .equals(Uri .parse(url).getHost())) return null ;
124- if (AndroidacyUtil .Companion .isAndroidacyLink(url)) {
125- breadcrumb.setData(" url" , AndroidacyUtil .hideToken(url));
130+ options.beforeBreadcrumb =
131+ BeforeBreadcrumbCallback { breadcrumb: Breadcrumb , _: Hint ? ->
132+ val url = breadcrumb.getData(" url" ) as String?
133+ if (url.isNullOrEmpty()) return @BeforeBreadcrumbCallback null
134+ if (" cloudflare-dns.com" == Uri .parse(url).host) {
135+ return @BeforeBreadcrumbCallback null
136+ }
137+ if (isAndroidacyLink(url)) {
138+ breadcrumb.setData(" url" , hideToken(url))
139+ }
140+ breadcrumb
126141 }
127- return breadcrumb;
128- });
129142 }
130- });
143+ }
131144 }
132145
133- public static void addSentryBreadcrumb(SentryBreadcrumb sentryBreadcrumb) {
146+ fun addSentryBreadcrumb (sentryBreadcrumb : SentryBreadcrumb ) {
134147 if (MainApplication .isCrashReportingEnabled()) {
135- Sentry .addBreadcrumb(sentryBreadcrumb.breadcrumb);
148+ Sentry .addBreadcrumb(sentryBreadcrumb.breadcrumb)
136149 }
137150 }
138-
139- @SuppressWarnings(" unused" )
140- public static boolean isSentryEnabled() {
141- return sentryEnabled;
142- }
143- }
151+ }
0 commit comments