diff --git a/atom/common/api/atom_api_crash_reporter.cc b/atom/common/api/atom_api_crash_reporter.cc index 9386dda8637e..e396356cdbb8 100644 --- a/atom/common/api/atom_api_crash_reporter.cc +++ b/atom/common/api/atom_api_crash_reporter.cc @@ -31,10 +31,34 @@ struct Converter > { } }; +template<> +struct Converter > { + static v8::Local ToV8(v8::Isolate* isolate, + const std::vector< + crash_reporter::CrashReporter::UploadReportResult>& reports) { + v8::Local result(v8::Array::New(isolate, reports.size())); + for (size_t i = 0; i < reports.size(); ++i) { + mate::Dictionary dict(isolate, v8::Object::New(isolate)); + dict.Set("date", reports[i].first); + dict.Set("id", reports[i].second); + v8::TryCatch try_catch; + result->Set(static_cast(i), dict.GetHandle()); + if (try_catch.HasCaught()) + LOG(ERROR) << "Setter for index " << i << " threw an exception."; + } + return result; + } +}; + } // namespace mate namespace { +std::vector +GetUploadedReports() { + return (crash_reporter::CrashReporter::GetInstance())->GetUploadedReports(); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { using crash_reporter::CrashReporter; @@ -42,6 +66,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("start", base::Bind(&CrashReporter::Start, base::Unretained(CrashReporter::GetInstance()))); + dict.SetMethod("_getUploadedReports", &GetUploadedReports); } } // namespace diff --git a/atom/common/api/lib/crash-reporter.coffee b/atom/common/api/lib/crash-reporter.coffee index d87ff9ea772f..c151ff7f71c8 100644 --- a/atom/common/api/lib/crash-reporter.coffee +++ b/atom/common/api/lib/crash-reporter.coffee @@ -41,6 +41,10 @@ class CrashReporter start() getLastCrashReport: -> + if process.platform is 'darwin' + reports = binding._getUploadedReports() + return if reports.length > 0 then reports[0] else null + tmpdir = if process.platform is 'win32' os.tmpdir() diff --git a/atom/common/crash_reporter/crash_reporter.cc b/atom/common/crash_reporter/crash_reporter.cc index 0a02086056b8..5d1e2146cc86 100644 --- a/atom/common/crash_reporter/crash_reporter.cc +++ b/atom/common/crash_reporter/crash_reporter.cc @@ -39,4 +39,8 @@ void CrashReporter::SetUploadParameters(const StringMap& parameters) { SetUploadParameters(); } +std::vector CrashReporter::GetUploadedReports() { + return std::vector(); +} + } // namespace crash_reporter diff --git a/atom/common/crash_reporter/crash_reporter.h b/atom/common/crash_reporter/crash_reporter.h index 43548a105b6c..c81111b596bd 100644 --- a/atom/common/crash_reporter/crash_reporter.h +++ b/atom/common/crash_reporter/crash_reporter.h @@ -7,6 +7,7 @@ #include #include +#include #include "base/basictypes.h" @@ -15,6 +16,7 @@ namespace crash_reporter { class CrashReporter { public: typedef std::map StringMap; + typedef std::pair UploadReportResult; // upload-date, id static CrashReporter* GetInstance(); @@ -25,6 +27,8 @@ class CrashReporter { bool skip_system_crash_handler, const StringMap& extra_parameters); + virtual std::vector GetUploadedReports(); + protected: CrashReporter(); virtual ~CrashReporter(); diff --git a/atom/common/crash_reporter/crash_reporter_mac.h b/atom/common/crash_reporter/crash_reporter_mac.h index 86f216bf5575..25eb0e28ba95 100644 --- a/atom/common/crash_reporter/crash_reporter_mac.h +++ b/atom/common/crash_reporter/crash_reporter_mac.h @@ -43,6 +43,8 @@ class CrashReporterMac : public CrashReporter { void SetCrashKeyValue(const base::StringPiece& key, const base::StringPiece& value); + std::vector GetUploadedReports() override; + scoped_ptr simple_string_dictionary_; scoped_ptr crash_report_database_; diff --git a/atom/common/crash_reporter/crash_reporter_mac.mm b/atom/common/crash_reporter/crash_reporter_mac.mm index fe55475c051e..3cb3063d079b 100644 --- a/atom/common/crash_reporter/crash_reporter_mac.mm +++ b/atom/common/crash_reporter/crash_reporter_mac.mm @@ -96,6 +96,39 @@ void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key, simple_string_dictionary_->SetKeyValue(key.data(), value.data()); } +std::vector +CrashReporterMac::GetUploadedReports() { + std::vector uploaded_reports; + + if (!crash_report_database_) { + return uploaded_reports; + } + + std::vector completed_reports; + crashpad::CrashReportDatabase::OperationStatus status = + crash_report_database_->GetCompletedReports(&completed_reports); + if (status != crashpad::CrashReportDatabase::kNoError) { + return uploaded_reports; + } + + for (const crashpad::CrashReportDatabase::Report& completed_report : + completed_reports) { + if (completed_report.uploaded) { + uploaded_reports.push_back( + UploadReportResult(static_cast(completed_report.creation_time), + completed_report.id)); + } + } + + struct { + bool operator()(const UploadReportResult& a, const UploadReportResult& b) { + return a.first >= b.first; + } + } sort_by_time; + std::sort(uploaded_reports.begin(), uploaded_reports.end(), sort_by_time); + return uploaded_reports; +} + // static CrashReporterMac* CrashReporterMac::GetInstance() { return Singleton::get();