public StartupProcessorExecutor(@NonNull final Context context, @NonNull final CoreConfiguration config, @NonNull SchedulerStarter schedulerStarter) { this.context = context; this.config = config; this.reportLocator = new ReportLocator(context); this.schedulerStarter = schedulerStarter; this.fileNameParser = new CrashReportFileNameParser(); }
/** * Cancel any pending crash reports. */ protected final void cancelReports() { new Thread(() -> new BulkReportDeleter(this).deleteReports(false, 0)).start(); }
ReportMigrator(@NonNull Context context) { this.context = context; this.reportLocator = new ReportLocator(context); }
/** * Store a report * * @param file the file to store in * @param crashData the content */ private void saveCrashReportFile(@NonNull File file, @NonNull CrashReportData crashData) { try { if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Writing crash report file " + file); final CrashReportPersister persister = new CrashReportPersister(); persister.store(crashData, file); } catch (Exception e) { ACRA.log.e(LOG_TAG, "An error occurred while writing the report file...", e); } } }
/** * @param approved Whether to delete approved or unapproved reports. * @param nrToKeep Number of latest reports to keep. */ public void deleteReports(boolean approved, int nrToKeep) { final File[] files = approved ? reportLocator.getApprovedReports() : reportLocator.getUnapprovedReports(); Arrays.sort(files, new LastModifiedComparator()); for (int i = 0; i < files.length - nrToKeep; i++) { if (!files[i].delete()) { ACRA.log.w(LOG_TAG, "Could not delete report : " + files[i]); } } } }
final CrashReportPersister persister = new CrashReportPersister(); final CrashReportData previousCrashReport = persister.load(reportFile); sendCrashReport(previousCrashReport); IOUtils.deleteFile(reportFile);
final File[] reports = locator.getApprovedReports(); final CrashReportFileNameParser fileNameParser = new CrashReportFileNameParser(); boolean anyNonSilent = false; for (final File report : reports) { final boolean isNonSilent = !fileNameParser.isSilent(report.getName()); if (onlySendSilentReports && isNonSilent) { continue;
public ApplicationStartupProcessor(@NonNull Context context, @NonNull CoreConfiguration config) { this.context = context; this.config = config; reportDeleter = new BulkReportDeleter(context); }
@NonNull private File getReportFileName(@NonNull CrashReportData crashData) { final String timestamp = crashData.getString(USER_CRASH_DATE); final String isSilent = crashData.getString(IS_SILENT); final String fileName = timestamp + (isSilent != null ? ACRAConstants.SILENT_SUFFIX : "") + ACRAConstants.REPORTFILE_EXTENSION; final ReportLocator reportLocator = new ReportLocator(context); return new File(reportLocator.getUnapprovedFolder(), fileName); }
void migrate() { ACRA.log.i(LOG_TAG, "Migrating unsent ACRA reports to new file locations"); final File[] reportFiles = getCrashReportFiles(); for (final File file : reportFiles) { // Move it to unapproved or approved folders. final String fileName = file.getName(); if (fileNameParser.isApproved(fileName)) { if (file.renameTo(new File(reportLocator.getApprovedFolder(), fileName))) { if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Cold not migrate unsent ACRA crash report : " + fileName); } } else { if (file.renameTo(new File(reportLocator.getUnapprovedFolder(), fileName))) { if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Cold not migrate unsent ACRA crash report : " + fileName); } } } ACRA.log.i(LOG_TAG, "Migrated " + reportFiles.length + " unsent reports"); }
/** * Delete any old unsent reports if this is a newer version of the app than when we last started. */ private void deleteUnsentReportsFromOldAppVersion() { final SharedPreferences prefs = new SharedPreferencesFactory(context, config).create(); final long lastVersionNr = prefs.getInt(ACRA.PREF_LAST_VERSION_NR, 0); final int appVersion = getAppVersion(); if (appVersion > lastVersionNr) { reportDeleter.deleteReports(true, 0); reportDeleter.deleteReports(false, 0); prefs.edit().putInt(ACRA.PREF_LAST_VERSION_NR, appVersion).apply(); } }
/** * @return Approved reports sorted by creation time. */ @NonNull public File[] getApprovedReports() { final File[] reports = getApprovedFolder().listFiles(); if (reports == null) { return new File[0]; } Arrays.sort(reports, new LastModifiedComparator()); return reports; } }
@NonNull @Override public File getFile(@NonNull Context context, @NonNull String fileName) { return (fileName.startsWith("/") ? Directory.ROOT : Directory.FILES).getFile(context, fileName); } },
@NonNull public File[] getUnapprovedReports() { final File[] reports = getUnapprovedFolder().listFiles(); if (reports == null) { return new File[0]; } return reports; }
/** * Returns true if the report is considered as approved. * <p> * This includes: * </p> * <ul> * <li>Reports which were pending when the user agreed to send a report in the NOTIFICATION mode Dialog.</li> * <li>Explicit silent reports</li> * </ul> * * @param reportFileName Name of report to check whether it is approved to be sent. * @return True if a report can be sent. * @deprecated use {@link ReportLocator#getApprovedReports()} and {@link ReportLocator#getUnapprovedReports()} instead */ @Deprecated public boolean isApproved(@NonNull String reportFileName) { return isSilent(reportFileName) || reportFileName.contains(ACRAConstants.APPROVED_SUFFIX); }
/** * Starts a process to start sending outstanding error reports. * * @param report If not null, this report will be approved before scheduling. * @param onlySendSilentReports If true then only send silent reports. */ public void scheduleReports(@Nullable File report, boolean onlySendSilentReports) { if (report != null) { if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Mark " + report.getName() + " as approved."); final File approvedReport = new File(locator.getApprovedFolder(), report.getName()); if (!report.renameTo(approvedReport)) { ACRA.log.w(LOG_TAG, "Could not rename approved report from " + report + " to " + approvedReport); } } if (ACRA.DEV_LOGGING) ACRA.log.d(LOG_TAG, "Schedule report sending"); senderScheduler.scheduleReportSending(onlySendSilentReports); }
/** * Get an uri for this content provider for the given file * * @param context a context * @param directory the directory, to with the path is relative * @param relativePath the file path * @return the uri */ @SuppressWarnings("WeakerAccess") @NonNull public static Uri getUriForFile(@NonNull Context context, @NonNull Directory directory, @NonNull String relativePath) { final Uri.Builder builder = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(getAuthority(context)) .appendPath(directory.name().toLowerCase()); for (String segment : relativePath.split(Pattern.quote(File.separator))) { if (segment.length() > 0) { builder.appendPath(segment); } } return builder.build(); }
public SendingConductor(@NonNull Context context, @NonNull CoreConfiguration config) { this.context = context; this.config = config; locator = new ReportLocator(context); }
@Override void collect(@NonNull ReportField reportField, @NonNull Context context, @NonNull CoreConfiguration config, @NonNull ReportBuilder reportBuilder, @NonNull CrashReportData target) throws IOException { target.put(ReportField.APPLICATION_LOG, new StreamReader(config.applicationLogFileDir().getFile(context, config.applicationLogFile())) .setLimit(config.applicationLogFileLines()).read()); } }
public BulkReportDeleter(@NonNull Context context) { this.reportLocator = new ReportLocator(context); }