4343 */
4444public class BacktraceDatabase implements Database {
4545
46- private static boolean _timerBackgroundWork = false ;
4746 private static Timer _timer ;
4847 private transient final String LOG_TAG = BacktraceDatabase .class .getSimpleName ();
4948 private Api BacktraceApi ;
@@ -96,21 +95,25 @@ public BacktraceDatabase(Context context, BacktraceDatabaseSettings databaseSett
9695 throw new IllegalArgumentException ("Database settings or application context is null" );
9796 }
9897
99- if (databaseSettings .getDatabasePath () == null || databaseSettings .getDatabasePath ().isEmpty ()) {
98+ if (databaseSettings .getDatabasePath () == null || databaseSettings .getDatabasePath ()
99+ .isEmpty ()) {
100100 throw new IllegalArgumentException ("Database path is null or empty" );
101101 }
102102
103103 if (!FileHelper .isFileExists (databaseSettings .getDatabasePath ())) {
104104 boolean createDirs = new File (databaseSettings .getDatabasePath ()).mkdirs ();
105105 if (!createDirs || !FileHelper .isFileExists (databaseSettings .getDatabasePath ())) {
106- throw new IllegalArgumentException ("Incorrect database path or application " + "doesn't have permission to write to this path" );
106+ throw new IllegalArgumentException ("Incorrect database path or application " +
107+ "doesn't have permission to write to this path" );
107108 }
108109 }
109110
110111 this ._applicationContext = context ;
111112 this .databaseSettings = databaseSettings ;
112113 this .backtraceDatabaseContext = new BacktraceDatabaseContext (databaseSettings );
113- this .backtraceDatabaseFileContext = new BacktraceDatabaseFileContext (this .getDatabasePath (), this .databaseSettings .getMaxDatabaseSize (), this .databaseSettings .getMaxRecordCount ());
114+ this .backtraceDatabaseFileContext = new BacktraceDatabaseFileContext (this .getDatabasePath (),
115+ this .databaseSettings .getMaxDatabaseSize (), this .databaseSettings
116+ .getMaxRecordCount ());
114117 this .breadcrumbs = new BacktraceBreadcrumbs (getDatabasePath ());
115118 this .crashHandlerConfiguration = new CrashHandlerConfiguration ();
116119 }
@@ -136,7 +139,8 @@ public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials
136139 * @param credentials Backtrace credentials
137140 * @param enableClientSideUnwinding Enable client side unwinding
138141 */
139- public Boolean setupNativeIntegration (BacktraceBase client , BacktraceCredentials credentials , boolean enableClientSideUnwinding ) {
142+ public Boolean setupNativeIntegration (BacktraceBase client , BacktraceCredentials credentials ,
143+ boolean enableClientSideUnwinding ) {
140144 return setupNativeIntegration (client , credentials , enableClientSideUnwinding , UnwindingMode .REMOTE_DUMPWITHOUTCRASH );
141145 }
142146
@@ -153,10 +157,10 @@ public void useNativeCommunication(NativeCommunication nativeCommunication) {
153157 * @param client Backtrace client
154158 * @param credentials Backtrace credentials
155159 * @param enableClientSideUnwinding Enable client side unwinding
156- * @param unwindingMode Unwinding mode to use for client side
157- * unwinding
160+ * @param unwindingMode Unwinding mode to use for client side unwinding
158161 */
159- public Boolean setupNativeIntegration (BacktraceBase client , BacktraceCredentials credentials , boolean enableClientSideUnwinding , UnwindingMode unwindingMode ) {
162+ public Boolean setupNativeIntegration (BacktraceBase client , BacktraceCredentials credentials ,
163+ boolean enableClientSideUnwinding , UnwindingMode unwindingMode ) {
160164 // avoid initialization when database doesn't exist
161165 if (_enable == false || getSettings () == null ) {
162166 return false ;
@@ -194,7 +198,15 @@ public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials
194198
195199 ApplicationInfo applicationInfo = _applicationContext .getApplicationInfo ();
196200
197- _enabledNativeIntegration = nativeCommunication .initializeJavaCrashHandler (minidumpSubmissionUrl , crashpadDatabaseDirectory , this .crashHandlerConfiguration .getClassPath (), keys , values , attachmentPaths , this .crashHandlerConfiguration .getCrashHandlerEnvironmentVariables (applicationInfo ).toArray (new String [0 ]));
201+ _enabledNativeIntegration =
202+ nativeCommunication .initializeJavaCrashHandler (minidumpSubmissionUrl ,
203+ crashpadDatabaseDirectory ,
204+ this .crashHandlerConfiguration .getClassPath (),
205+ keys ,
206+ values ,
207+ attachmentPaths ,
208+ this .crashHandlerConfiguration .getCrashHandlerEnvironmentVariables (applicationInfo ).toArray (new String [0 ])
209+ );
198210
199211 if (_enabledNativeIntegration && this .breadcrumbs .isEnabled ()) {
200212 this .breadcrumbs .setOnSuccessfulBreadcrumbAddEventListener (breadcrumbId -> {
@@ -252,7 +264,8 @@ public void start() {
252264
253265 this .removeOrphaned ();
254266
255- if (databaseSettings .getRetryBehavior () == RetryBehavior .ByInterval || databaseSettings .isAutoSendMode ()) {
267+ if (databaseSettings .getRetryBehavior () == RetryBehavior .ByInterval || databaseSettings
268+ .isAutoSendMode ()) {
256269 setupTimer ();
257270 }
258271
@@ -274,69 +287,64 @@ private void setupTimer() {
274287 @ Override
275288 public void run () {
276289 String dateTimeNow = Calendar .getInstance ().getTime ().toString ();
277- BacktraceLogger .d (LOG_TAG , "Timer - " + dateTimeNow );
290+ BacktraceLogger .d (LOG_TAG , "Backtrace DB Timer - " + dateTimeNow );
278291 if (backtraceDatabaseContext == null ) {
279- BacktraceLogger .w (LOG_TAG , "Timer - database context is null: " + dateTimeNow );
292+ BacktraceLogger .w (LOG_TAG , "Backtrace DB Timer - database context is null: " +
293+ dateTimeNow );
280294 return ;
281295 }
282296
283297 if (backtraceDatabaseContext .isEmpty ()) {
284- BacktraceLogger .d (LOG_TAG , "Timer - database is empty (no records): " + dateTimeNow );
298+ BacktraceLogger .d (LOG_TAG , "Backtrace DB Timer - database is empty (no records): " +
299+ dateTimeNow );
285300 return ;
286301 }
287302
288- if (_timerBackgroundWork ) {
289- BacktraceLogger .d (LOG_TAG , "Timer - another timer works now: " + dateTimeNow );
290- return ;
291- }
292-
293- BacktraceLogger .d (LOG_TAG , "Timer - continue working: " + dateTimeNow );
294- _timerBackgroundWork = true ;
295- _timer .cancel ();
296- _timer .purge ();
297- _timer = null ;
298-
299- BacktraceDatabaseRecord record = backtraceDatabaseContext .first ();
300- while (record != null ) {
301- final CountDownLatch threadWaiter = new CountDownLatch (1 );
302- BacktraceData backtraceData = record .getBacktraceData ();
303- if (backtraceData == null || backtraceData .getReport () == null ) {
304- BacktraceLogger .d (LOG_TAG , "Timer - backtrace data or report is null - " + "deleting record" );
305- delete (record );
306- } else {
307- final BacktraceDatabaseRecord currentRecord = record ;
308- BacktraceApi .send (backtraceData , new OnServerResponseEventListener () {
309- @ Override
310- public void onEvent (BacktraceResult backtraceResult ) {
311- if (backtraceResult .status == BacktraceResultStatus .Ok ) {
312- BacktraceLogger .d (LOG_TAG , "Timer - deleting record" );
313- delete (currentRecord );
314- } else {
315- BacktraceLogger .d (LOG_TAG , "Timer - closing record" );
316- currentRecord .close ();
317- // backtraceDatabaseContext.incrementBatchRetry(); TODO: consider another way to
318- // remove some records after few retries
303+ try {
304+ BacktraceDatabaseRecord record = backtraceDatabaseContext .first ();
305+ while (record != null ) {
306+ final CountDownLatch threadWaiter = new CountDownLatch (1 );
307+ BacktraceData backtraceData = record .getBacktraceData ();
308+ if (backtraceData == null || backtraceData .getReport () == null ) {
309+ BacktraceLogger .d (LOG_TAG , "Backtrace DB Timer - backtrace data or report is null - " +
310+ "deleting record" );
311+ delete (record );
312+ } else {
313+ final BacktraceDatabaseRecord currentRecord = record ;
314+ BacktraceApi .send (backtraceData , new OnServerResponseEventListener () {
315+ @ Override
316+ public void onEvent (BacktraceResult backtraceResult ) {
317+ if (backtraceResult .status == BacktraceResultStatus .Ok ) {
318+ BacktraceLogger .d (LOG_TAG , "Backtrace DB Timer - deleting record" );
319+ delete (currentRecord );
320+ } else {
321+ BacktraceLogger .d (LOG_TAG , "Backtrace DB Timer - closing record" );
322+ currentRecord .close ();
323+ // backtraceDatabaseContext.incrementBatchRetry(); TODO: consider another way to remove some records after few retries
324+ }
325+ threadWaiter .countDown ();
319326 }
320- threadWaiter .countDown ();
327+ });
328+ try {
329+ threadWaiter .await ();
330+ } catch (Exception ex ) {
331+ BacktraceLogger .e (LOG_TAG ,
332+ "Error during waiting for result in Backtrace DB Timer" , ex
333+ );
334+ }
335+ if (currentRecord .valid () && !currentRecord .locked ) {
336+ BacktraceLogger .d (LOG_TAG , "Backtrace DB Timer - record is valid and unlocked" );
337+ break ;
321338 }
322- });
323- try {
324- threadWaiter .await ();
325- } catch (Exception ex ) {
326- BacktraceLogger .e (LOG_TAG , "Error during waiting for result in Timer" , ex );
327- }
328- if (currentRecord .valid () && !currentRecord .locked ) {
329- BacktraceLogger .d (LOG_TAG , "Timer - record is valid and unlocked" );
330- break ;
331339 }
340+ record = backtraceDatabaseContext .first ();
332341 }
333- record = backtraceDatabaseContext .first ();
334342 }
335- BacktraceLogger . d ( LOG_TAG , "Setup new timer" );
336- _timerBackgroundWork = false ;
337- setupTimer ();
343+ catch ( Exception e ) {
344+ BacktraceLogger . e ( LOG_TAG , "Exception in Backtrace DB timer" , e ) ;
345+ }
338346 }
339- }, databaseSettings .getRetryInterval () * 1000L );
347+ }, databaseSettings .getRetryInterval () * 1000L , databaseSettings . getRetryInterval () * 1000L );
340348 }
341349
342350 public void flush () {
0 commit comments