13
13
import io .sentry .SendFireAndForgetOutboxSender ;
14
14
import io .sentry .SentryLevel ;
15
15
import io .sentry .SentryOptions ;
16
+ import io .sentry .android .fragment .FragmentLifecycleIntegration ;
17
+ import io .sentry .android .timber .SentryTimberIntegration ;
16
18
import io .sentry .util .Objects ;
17
19
import java .io .BufferedInputStream ;
18
20
import java .io .File ;
@@ -43,7 +45,7 @@ static void init(final @NotNull SentryAndroidOptions options, final @NotNull Con
43
45
Objects .requireNonNull (context , "The application context is required." );
44
46
Objects .requireNonNull (options , "The options object is required." );
45
47
46
- init (options , context , new AndroidLogger ());
48
+ init (options , context , new AndroidLogger (), false , false );
47
49
}
48
50
49
51
/**
@@ -52,12 +54,16 @@ static void init(final @NotNull SentryAndroidOptions options, final @NotNull Con
52
54
* @param options the SentryOptions
53
55
* @param context the Application context
54
56
* @param logger the ILogger interface
57
+ * @param isFragmentAvailable whether the Fragment integration is available on the classpath
58
+ * @param isTimberAvailable whether the Timber integration is available on the classpath
55
59
*/
56
60
static void init (
57
61
final @ NotNull SentryAndroidOptions options ,
58
62
@ NotNull Context context ,
59
- final @ NotNull ILogger logger ) {
60
- init (options , context , logger , new BuildInfoProvider ());
63
+ final @ NotNull ILogger logger ,
64
+ final boolean isFragmentAvailable ,
65
+ final boolean isTimberAvailable ) {
66
+ init (options , context , logger , new BuildInfoProvider (), isFragmentAvailable , isTimberAvailable );
61
67
}
62
68
63
69
/**
@@ -67,13 +73,24 @@ static void init(
67
73
* @param context the Application context
68
74
* @param logger the ILogger interface
69
75
* @param buildInfoProvider the IBuildInfoProvider interface
76
+ * @param isFragmentAvailable whether the Fragment integration is available on the classpath
77
+ * @param isTimberAvailable whether the Timber integration is available on the classpath
70
78
*/
71
79
static void init (
72
80
final @ NotNull SentryAndroidOptions options ,
73
81
@ NotNull Context context ,
74
82
final @ NotNull ILogger logger ,
75
- final @ NotNull IBuildInfoProvider buildInfoProvider ) {
76
- init (options , context , logger , buildInfoProvider , new LoadClass ());
83
+ final @ NotNull IBuildInfoProvider buildInfoProvider ,
84
+ final boolean isFragmentAvailable ,
85
+ final boolean isTimberAvailable ) {
86
+ init (
87
+ options ,
88
+ context ,
89
+ logger ,
90
+ buildInfoProvider ,
91
+ new LoadClass (),
92
+ isFragmentAvailable ,
93
+ isTimberAvailable );
77
94
}
78
95
79
96
/**
@@ -84,13 +101,17 @@ static void init(
84
101
* @param logger the ILogger interface
85
102
* @param buildInfoProvider the IBuildInfoProvider interface
86
103
* @param loadClass the LoadClass wrapper
104
+ * @param isFragmentAvailable whether the Fragment integration is available on the classpath
105
+ * @param isTimberAvailable whether the Timber integration is available on the classpath
87
106
*/
88
107
static void init (
89
108
final @ NotNull SentryAndroidOptions options ,
90
109
@ NotNull Context context ,
91
110
final @ NotNull ILogger logger ,
92
111
final @ NotNull IBuildInfoProvider buildInfoProvider ,
93
- final @ NotNull LoadClass loadClass ) {
112
+ final @ NotNull LoadClass loadClass ,
113
+ final boolean isFragmentAvailable ,
114
+ final boolean isTimberAvailable ) {
94
115
Objects .requireNonNull (context , "The context is required." );
95
116
96
117
// it returns null if ContextImpl, so let's check for nullability
@@ -107,9 +128,16 @@ static void init(
107
128
ManifestMetadataReader .applyMetadata (context , options );
108
129
initializeCacheDirs (context , options );
109
130
110
- final ActivityFramesTracker activityFramesTracker = new ActivityFramesTracker (loadClass );
131
+ final ActivityFramesTracker activityFramesTracker =
132
+ new ActivityFramesTracker (loadClass , options .getLogger ());
111
133
installDefaultIntegrations (
112
- context , options , buildInfoProvider , loadClass , activityFramesTracker );
134
+ context ,
135
+ options ,
136
+ buildInfoProvider ,
137
+ loadClass ,
138
+ activityFramesTracker ,
139
+ isFragmentAvailable ,
140
+ isTimberAvailable );
113
141
114
142
readDefaultOptionValues (options , context );
115
143
@@ -124,15 +152,20 @@ private static void installDefaultIntegrations(
124
152
final @ NotNull SentryOptions options ,
125
153
final @ NotNull IBuildInfoProvider buildInfoProvider ,
126
154
final @ NotNull LoadClass loadClass ,
127
- final @ NotNull ActivityFramesTracker activityFramesTracker ) {
155
+ final @ NotNull ActivityFramesTracker activityFramesTracker ,
156
+ final boolean isFragmentAvailable ,
157
+ final boolean isTimberAvailable ) {
128
158
129
159
options .addIntegration (
130
160
new SendCachedEnvelopeFireAndForgetIntegration (
131
161
new SendFireAndForgetEnvelopeSender (() -> options .getCacheDirPath ())));
132
162
133
163
// Integrations are registered in the same order. NDK before adding Watch outbox,
134
164
// because sentry-native move files around and we don't want to watch that.
135
- final Class <?> sentryNdkClass = loadNdkIfAvailable (options , buildInfoProvider , loadClass );
165
+ final Class <?> sentryNdkClass =
166
+ isNdkAvailable (buildInfoProvider )
167
+ ? loadClass .loadClass (SENTRY_NDK_CLASS_NAME , options .getLogger ())
168
+ : null ;
136
169
options .addIntegration (new NdkIntegration (sentryNdkClass ));
137
170
138
171
// this integration uses android.os.FileObserver, we can't move to sentry
@@ -155,12 +188,18 @@ private static void installDefaultIntegrations(
155
188
new ActivityLifecycleIntegration (
156
189
(Application ) context , buildInfoProvider , activityFramesTracker ));
157
190
options .addIntegration (new UserInteractionIntegration ((Application ) context , loadClass ));
191
+ if (isFragmentAvailable ) {
192
+ options .addIntegration (new FragmentLifecycleIntegration ((Application ) context , true , true ));
193
+ }
158
194
} else {
159
195
options
160
196
.getLogger ()
161
197
.log (
162
198
SentryLevel .WARNING ,
163
- "ActivityLifecycle and UserInteraction Integrations need an Application class to be installed." );
199
+ "ActivityLifecycle, FragmentLifecycle and UserInteraction Integrations need an Application class to be installed." );
200
+ }
201
+ if (isTimberAvailable ) {
202
+ options .addIntegration (new SentryTimberIntegration ());
164
203
}
165
204
options .addIntegration (new AppComponentsBreadcrumbsIntegration (context ));
166
205
options .addIntegration (new SystemEventsBreadcrumbsIntegration (context ));
@@ -257,24 +296,4 @@ private static void initializeCacheDirs(
257
296
private static boolean isNdkAvailable (final @ NotNull IBuildInfoProvider buildInfoProvider ) {
258
297
return buildInfoProvider .getSdkInfoVersion () >= Build .VERSION_CODES .JELLY_BEAN ;
259
298
}
260
-
261
- private static @ Nullable Class <?> loadNdkIfAvailable (
262
- final @ NotNull SentryOptions options ,
263
- final @ NotNull IBuildInfoProvider buildInfoProvider ,
264
- final @ NotNull LoadClass loadClass ) {
265
- if (isNdkAvailable (buildInfoProvider )) {
266
- try {
267
- return loadClass .loadClass (SENTRY_NDK_CLASS_NAME );
268
- } catch (ClassNotFoundException e ) {
269
- options .getLogger ().log (SentryLevel .ERROR , "Failed to load SentryNdk." , e );
270
- } catch (UnsatisfiedLinkError e ) {
271
- options
272
- .getLogger ()
273
- .log (SentryLevel .ERROR , "Failed to load (UnsatisfiedLinkError) SentryNdk." , e );
274
- } catch (Throwable e ) {
275
- options .getLogger ().log (SentryLevel .ERROR , "Failed to initialize SentryNdk." , e );
276
- }
277
- }
278
- return null ;
279
- }
280
299
}
0 commit comments