| Index: third_party/crashpad/crashpad/client/crash_report_database_win.cc
|
| diff --git a/third_party/crashpad/crashpad/client/crash_report_database_win.cc b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
|
| index c3869c58f5b6cf699552ea8757050f4bd6c194f1..c0bc42b888159fa74b504eb77b56c4ce578d08c0 100644
|
| --- a/third_party/crashpad/crashpad/client/crash_report_database_win.cc
|
| +++ b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
|
| @@ -103,6 +103,14 @@ enum class ReportState {
|
| kCompleted,
|
| };
|
|
|
| +enum {
|
| + //! \brief Corresponds to uploaded bit of the report state.
|
| + kAttributeUploaded = 1 << 0,
|
| +
|
| + //! \brief Corresponds to upload_explicity_requested bit of the report state.
|
| + kAttributeUploadExplicitlyRequested = 1 << 1,
|
| +};
|
| +
|
| struct MetadataFileReportRecord {
|
| // Note that this default constructor does no initialization. It is used only
|
| // to create an array of records that are immediately initialized by reading
|
| @@ -121,7 +129,7 @@ struct MetadataFileReportRecord {
|
| int64_t last_upload_attempt_time; // Holds a time_t.
|
| int32_t upload_attempts;
|
| int32_t state; // A ReportState.
|
| - uint8_t uploaded; // Boolean, 0 or 1.
|
| + uint8_t attributes; // Bitfield of kAttribute*.
|
| uint8_t padding[7];
|
| };
|
|
|
| @@ -151,7 +159,10 @@ MetadataFileReportRecord::MetadataFileReportRecord(const ReportDisk& report,
|
| last_upload_attempt_time(report.last_upload_attempt_time),
|
| upload_attempts(report.upload_attempts),
|
| state(static_cast<uint32_t>(report.state)),
|
| - uploaded(report.uploaded) {
|
| + attributes((report.uploaded ? kAttributeUploaded : 0) |
|
| + (report.upload_explicitly_requested
|
| + ? kAttributeUploadExplicitlyRequested
|
| + : 0)) {
|
| memset(&padding, 0, sizeof(padding));
|
| }
|
|
|
| @@ -164,10 +175,12 @@ ReportDisk::ReportDisk(const MetadataFileReportRecord& record,
|
| base::UTF8ToUTF16(&string_table[record.file_path_index]));
|
| id = &string_table[record.id_index];
|
| creation_time = record.creation_time;
|
| - uploaded = record.uploaded != 0;
|
| last_upload_attempt_time = record.last_upload_attempt_time;
|
| upload_attempts = record.upload_attempts;
|
| state = static_cast<ReportState>(record.state);
|
| + uploaded = (record.attributes & kAttributeUploaded) != 0;
|
| + upload_explicitly_requested =
|
| + (record.attributes & kAttributeUploadExplicitlyRequested) != 0;
|
| }
|
|
|
| ReportDisk::ReportDisk(const UUID& uuid,
|
| @@ -577,6 +590,7 @@ class CrashReportDatabaseWin : public CrashReportDatabase {
|
| const std::string& id) override;
|
| OperationStatus SkipReportUpload(const UUID& uuid) override;
|
| OperationStatus DeleteReport(const UUID& uuid) override;
|
| + OperationStatus RequestUpload(const UUID& uuid) override;
|
|
|
| private:
|
| std::unique_ptr<Metadata> AcquireMetadata();
|
| @@ -773,8 +787,14 @@ OperationStatus CrashReportDatabaseWin::RecordUploadAttempt(
|
| report_disk->id = id;
|
| report_disk->last_upload_attempt_time = now;
|
| report_disk->upload_attempts++;
|
| - report_disk->state =
|
| - successful ? ReportState::kCompleted : ReportState::kPending;
|
| + if (successful) {
|
| + report_disk->state = ReportState::kCompleted;
|
| + report_disk->upload_explicitly_requested = false;
|
| + } else {
|
| + report_disk->state = ReportState::kPending;
|
| + report_disk->upload_explicitly_requested =
|
| + report->upload_explicitly_requested;
|
| + }
|
|
|
| if (!settings_.SetLastUploadAttemptTime(now))
|
| return kDatabaseError;
|
| @@ -811,8 +831,10 @@ OperationStatus CrashReportDatabaseWin::SkipReportUpload(const UUID& uuid) {
|
| ReportDisk* report_disk;
|
| OperationStatus os = metadata->FindSingleReportAndMarkDirty(
|
| uuid, ReportState::kPending, &report_disk);
|
| - if (os == kNoError)
|
| + if (os == kNoError) {
|
| report_disk->state = ReportState::kCompleted;
|
| + report_disk->upload_explicitly_requested = false;
|
| + }
|
| return os;
|
| }
|
|
|
| @@ -831,6 +853,37 @@ std::unique_ptr<CrashReportDatabase> InitializeInternal(
|
| : std::unique_ptr<CrashReportDatabaseWin>();
|
| }
|
|
|
| +OperationStatus CrashReportDatabaseWin::RequestUpload(const UUID& uuid) {
|
| + INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
| +
|
| + std::unique_ptr<Metadata> metadata(AcquireMetadata());
|
| + if (!metadata)
|
| + return kDatabaseError;
|
| +
|
| + ReportDisk* report_disk;
|
| + // TODO(gayane): Search for the report only once regardless of its state.
|
| + OperationStatus os = metadata->FindSingleReportAndMarkDirty(
|
| + uuid, ReportState::kCompleted, &report_disk);
|
| + if (os == kBusyError) {
|
| + os = metadata->FindSingleReportAndMarkDirty(
|
| + uuid, ReportState::kPending, &report_disk);
|
| + }
|
| +
|
| + if (os != kNoError)
|
| + return os;
|
| +
|
| + // If the crash report has already been uploaded, don't request new upload.
|
| + if (report_disk->uploaded)
|
| + return kCannotRequestUpload;
|
| +
|
| + // Mark the crash report as having upload explicitly requested by the user,
|
| + // and move it to the pending state.
|
| + report_disk->upload_explicitly_requested = true;
|
| + report_disk->state = ReportState::kPending;
|
| +
|
| + return kNoError;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // static
|
|
|