1919import io .sentry .util .HintUtils ;
2020import io .sentry .util .LazyEvaluator ;
2121import io .sentry .util .Objects ;
22+
2223import java .util .Collections ;
2324import java .util .List ;
2425import java .util .Locale ;
2728import java .util .concurrent .Executors ;
2829import java .util .concurrent .Future ;
2930import java .util .concurrent .RejectedExecutionException ;
31+
3032import org .jetbrains .annotations .NotNull ;
3133import org .jetbrains .annotations .Nullable ;
3234import org .jetbrains .annotations .TestOnly ;
3335
3436final class DefaultAndroidEventProcessor implements EventProcessor {
3537
36- @ TestOnly final Context context ;
38+ @ TestOnly
39+ final Context context ;
3740
3841 private final @ NotNull BuildInfoProvider buildInfoProvider ;
3942 private final @ NotNull SentryAndroidOptions options ;
4043 private final @ Nullable Future <DeviceInfoUtil > deviceInfoUtil ;
4144 private final @ NotNull LazyEvaluator <String > deviceFamily =
42- new LazyEvaluator <>(() -> ContextUtils .getFamily (NoOpLogger .getInstance ()));
45+ new LazyEvaluator <>(() -> ContextUtils .getFamily (NoOpLogger .getInstance ()));
4346
4447 public DefaultAndroidEventProcessor (
45- final @ NotNull Context context ,
46- final @ NotNull BuildInfoProvider buildInfoProvider ,
47- final @ NotNull SentryAndroidOptions options ) {
48+ final @ NotNull Context context ,
49+ final @ NotNull BuildInfoProvider buildInfoProvider ,
50+ final @ NotNull SentryAndroidOptions options ) {
4851 this .context =
49- Objects .requireNonNull (
50- ContextUtils .getApplicationContext (context ), "The application context is required." );
52+ Objects .requireNonNull (
53+ ContextUtils .getApplicationContext (context ), "The application context is required." );
5154 this .buildInfoProvider =
52- Objects .requireNonNull (buildInfoProvider , "The BuildInfoProvider is required." );
55+ Objects .requireNonNull (buildInfoProvider , "The BuildInfoProvider is required." );
5356 this .options = Objects .requireNonNull (options , "The options object is required." );
5457
5558 // don't ref. to method reference, theres a bug on it
@@ -59,7 +62,7 @@ public DefaultAndroidEventProcessor(
5962 final @ NotNull ExecutorService executorService = Executors .newSingleThreadExecutor ();
6063 try {
6164 deviceInfoUtil =
62- executorService .submit (() -> DeviceInfoUtil .getInstance (this .context , options ));
65+ executorService .submit (() -> DeviceInfoUtil .getInstance (this .context , options ));
6366 } catch (RejectedExecutionException e ) {
6467 deviceInfoUtil = null ;
6568 options .getLogger ().log (SentryLevel .WARNING , "Device info caching task rejected." , e );
@@ -118,7 +121,7 @@ private static void fixExceptionOrder(final @NotNull SentryEvent event) {
118121 if (frames != null ) {
119122 for (final @ NotNull SentryStackFrame frame : frames ) {
120123 if ("com.android.internal.os.RuntimeInit$MethodAndArgsCaller"
121- .equals (frame .getModule ())) {
124+ .equals (frame .getModule ())) {
122125 reverseExceptions = true ;
123126 break ;
124127 }
@@ -134,25 +137,25 @@ private static void fixExceptionOrder(final @NotNull SentryEvent event) {
134137 }
135138
136139 private void setCommons (
137- final @ NotNull SentryBaseEvent event ,
138- final boolean errorEvent ,
139- final boolean applyScopeData ) {
140+ final @ NotNull SentryBaseEvent event ,
141+ final boolean errorEvent ,
142+ final boolean applyScopeData ) {
140143 mergeUser (event );
141144 setDevice (event , errorEvent , applyScopeData );
142145 setSideLoadedInfo (event );
143146 }
144147
145148 private boolean shouldApplyScopeData (
146- final @ NotNull SentryBaseEvent event , final @ NotNull Hint hint ) {
149+ final @ NotNull SentryBaseEvent event , final @ NotNull Hint hint ) {
147150 if (HintUtils .shouldApplyScopeData (hint )) {
148151 return true ;
149152 } else {
150153 options
151- .getLogger ()
152- .log (
153- SentryLevel .DEBUG ,
154- "Event was cached so not applying data relevant to the current app execution/version: %s" ,
155- event .getEventId ());
154+ .getLogger ()
155+ .log (
156+ SentryLevel .DEBUG ,
157+ "Event was cached so not applying data relevant to the current app execution/version: %s" ,
158+ event .getEventId ());
156159 return false ;
157160 }
158161 }
@@ -174,29 +177,38 @@ private void mergeUser(final @NotNull SentryBaseEvent event) {
174177 }
175178
176179 private void setDevice (
177- final @ NotNull SentryBaseEvent event ,
178- final boolean errorEvent ,
179- final boolean applyScopeData ) {
180+ final @ NotNull SentryBaseEvent event ,
181+ final boolean errorEvent ,
182+ final boolean applyScopeData ) {
180183 if (event .getContexts ().getDevice () == null ) {
181- try {
182- event
184+ if (deviceInfoUtil != null ) {
185+ try {
186+ event
183187 .getContexts ()
184188 .setDevice (deviceInfoUtil .get ().collectDeviceInformation (errorEvent , applyScopeData ));
185- } catch (Throwable e ) {
186- options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" , e );
189+ } catch (Throwable e ) {
190+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" , e );
191+ }
192+ } else {
193+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" );
187194 }
188195 mergeOS (event );
189196 }
190197 }
191198
192199 private void mergeOS (final @ NotNull SentryBaseEvent event ) {
193200 final OperatingSystem currentOS = event .getContexts ().getOperatingSystem ();
194- try {
195- final OperatingSystem androidOS = deviceInfoUtil .get ().getOperatingSystem ();
196- // make Android OS the main OS using the 'os' key
197- event .getContexts ().setOperatingSystem (androidOS );
198- } catch (Throwable e ) {
199- options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve os system" , e );
201+
202+ if (deviceInfoUtil != null ) {
203+ try {
204+ final OperatingSystem androidOS = deviceInfoUtil .get ().getOperatingSystem ();
205+ // make Android OS the main OS using the 'os' key
206+ event .getContexts ().setOperatingSystem (androidOS );
207+ } catch (Throwable e ) {
208+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve os system" , e );
209+ }
210+ } else {
211+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" );
200212 }
201213
202214 if (currentOS != null ) {
@@ -214,14 +226,14 @@ private void mergeOS(final @NotNull SentryBaseEvent event) {
214226 private void setDevice (final @ NotNull SentryLogEvent event ) {
215227 try {
216228 event .setAttribute (
217- "device.brand" ,
218- new SentryLogEventAttributeValue (SentryAttributeType .STRING , Build .BRAND ));
229+ "device.brand" ,
230+ new SentryLogEventAttributeValue (SentryAttributeType .STRING , Build .BRAND ));
219231 event .setAttribute (
220- "device.model" ,
221- new SentryLogEventAttributeValue (SentryAttributeType .STRING , Build .MODEL ));
232+ "device.model" ,
233+ new SentryLogEventAttributeValue (SentryAttributeType .STRING , Build .MODEL ));
222234 event .setAttribute (
223- "device.family" ,
224- new SentryLogEventAttributeValue (SentryAttributeType .STRING , deviceFamily .getValue ()));
235+ "device.family" ,
236+ new SentryLogEventAttributeValue (SentryAttributeType .STRING , deviceFamily .getValue ()));
225237 } catch (Throwable e ) {
226238 options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" , e );
227239 }
@@ -230,18 +242,18 @@ private void setDevice(final @NotNull SentryLogEvent event) {
230242 private void setOs (final @ NotNull SentryLogEvent event ) {
231243 try {
232244 event .setAttribute (
233- "os.name" , new SentryLogEventAttributeValue (SentryAttributeType .STRING , "Android" ));
245+ "os.name" , new SentryLogEventAttributeValue (SentryAttributeType .STRING , "Android" ));
234246 event .setAttribute (
235- "os.version" ,
236- new SentryLogEventAttributeValue (SentryAttributeType .STRING , Build .VERSION .RELEASE ));
247+ "os.version" ,
248+ new SentryLogEventAttributeValue (SentryAttributeType .STRING , Build .VERSION .RELEASE ));
237249 } catch (Throwable e ) {
238250 options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve os system" , e );
239251 }
240252 }
241253
242254 // Data to be applied to events that was created in the running process
243255 private void processNonCachedEvent (
244- final @ NotNull SentryBaseEvent event , final @ NotNull Hint hint ) {
256+ final @ NotNull SentryBaseEvent event , final @ NotNull Hint hint ) {
245257 App app = event .getContexts ().getApp ();
246258 if (app == null ) {
247259 app = new App ();
@@ -273,18 +285,22 @@ private void setThreads(final @NotNull SentryEvent event, final @NotNull Hint hi
273285
274286 private void setPackageInfo (final @ NotNull SentryBaseEvent event , final @ NotNull App app ) {
275287 final PackageInfo packageInfo =
276- ContextUtils .getPackageInfo (
277- context , PackageManager .GET_PERMISSIONS , options .getLogger (), buildInfoProvider );
288+ ContextUtils .getPackageInfo (
289+ context , PackageManager .GET_PERMISSIONS , options .getLogger (), buildInfoProvider );
278290 if (packageInfo != null ) {
279291 String versionCode = ContextUtils .getVersionCode (packageInfo , buildInfoProvider );
280292
281293 setDist (event , versionCode );
282294
283295 @ Nullable DeviceInfoUtil deviceInfoUtil = null ;
284- try {
285- deviceInfoUtil = this .deviceInfoUtil .get ();
286- } catch (Throwable e ) {
287- options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" , e );
296+ if (this .deviceInfoUtil != null ) {
297+ try {
298+ deviceInfoUtil = this .deviceInfoUtil .get ();
299+ } catch (Throwable e ) {
300+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" , e );
301+ }
302+ } else {
303+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" );
288304 }
289305
290306 ContextUtils .setAppPackageInfo (packageInfo , buildInfoProvider , deviceInfoUtil , app );
@@ -300,7 +316,7 @@ private void setDist(final @NotNull SentryBaseEvent event, final @NotNull String
300316 private void setAppExtras (final @ NotNull App app , final @ NotNull Hint hint ) {
301317 app .setAppName (ContextUtils .getApplicationName (context ));
302318 final @ NotNull TimeSpan appStartTimeSpan =
303- AppStartMetrics .getInstance ().getAppStartTimeSpanWithFallback (options );
319+ AppStartMetrics .getInstance ().getAppStartTimeSpanWithFallback (options );
304320 if (appStartTimeSpan .hasStarted ()) {
305321 app .setAppStartTime (DateUtils .toUtilDate (appStartTimeSpan .getStartTimestamp ()));
306322 }
@@ -328,22 +344,26 @@ private void setAppExtras(final @NotNull App app, final @NotNull Hint hint) {
328344 }
329345
330346 private void setSideLoadedInfo (final @ NotNull SentryBaseEvent event ) {
331- try {
332- final ContextUtils .SideLoadedInfo sideLoadedInfo = deviceInfoUtil .get ().getSideLoadedInfo ();
333- if (sideLoadedInfo != null ) {
334- final @ NotNull Map <String , String > tags = sideLoadedInfo .asTags ();
335- for (Map .Entry <String , String > entry : tags .entrySet ()) {
336- event .setTag (entry .getKey (), entry .getValue ());
347+ if (deviceInfoUtil != null ) {
348+ try {
349+ final ContextUtils .SideLoadedInfo sideLoadedInfo = deviceInfoUtil .get ().getSideLoadedInfo ();
350+ if (sideLoadedInfo != null ) {
351+ final @ NotNull Map <String , String > tags = sideLoadedInfo .asTags ();
352+ for (Map .Entry <String , String > entry : tags .entrySet ()) {
353+ event .setTag (entry .getKey (), entry .getValue ());
354+ }
337355 }
356+ } catch (Throwable e ) {
357+ options .getLogger ().log (SentryLevel .ERROR , "Error getting side loaded info." , e );
338358 }
339- } catch ( Throwable e ) {
340- options .getLogger ().log (SentryLevel .ERROR , "Error getting side loaded info." , e );
359+ } else {
360+ options .getLogger ().log (SentryLevel .ERROR , "Failed to retrieve device info" );
341361 }
342362 }
343363
344364 @ Override
345365 public @ NotNull SentryTransaction process (
346- final @ NotNull SentryTransaction transaction , final @ NotNull Hint hint ) {
366+ final @ NotNull SentryTransaction transaction , final @ NotNull Hint hint ) {
347367 final boolean applyScopeData = shouldApplyScopeData (transaction , hint );
348368
349369 if (applyScopeData ) {
@@ -357,7 +377,7 @@ private void setSideLoadedInfo(final @NotNull SentryBaseEvent event) {
357377
358378 @ Override
359379 public @ NotNull SentryReplayEvent process (
360- final @ NotNull SentryReplayEvent event , final @ NotNull Hint hint ) {
380+ final @ NotNull SentryReplayEvent event , final @ NotNull Hint hint ) {
361381 final boolean applyScopeData = shouldApplyScopeData (event , hint );
362382 if (applyScopeData ) {
363383 processNonCachedEvent (event , hint );
0 commit comments