blob: 747a442eb76f8f0dd7eab98eeec8bced8c0c3c1d [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/feedback/system_logs/log_sources/crash_ids_source.h"
#include <string>
#include "base/bind.h"
#include "base/time/time.h"
#include "chrome/browser/crash_upload_list/crash_upload_list.h"
#include "components/feedback/feedback_report.h"
namespace system_logs {
namespace {
// The maximum number of crashes we retrieve from the crash list.
constexpr size_t kMaxCrashesCountToRetrieve = 10;
// The length of the crash ID string.
constexpr size_t kCrashIdStringSize = 16;
// We are only interested in crashes that took place within the last hour.
constexpr base::TimeDelta kOneHourTimeDelta = base::TimeDelta::FromHours(1);
} // namespace
CrashIdsSource::CrashIdsSource()
: SystemLogsSource("CrashId"),
crash_upload_list_(CreateCrashUploadList()),
pending_crash_list_loading_(false) {}
CrashIdsSource::~CrashIdsSource() {}
void CrashIdsSource::Fetch(const SysLogsSourceCallback& callback) {
// Unretained since we own these callbacks.
pending_requests_.emplace_back(base::Bind(
&CrashIdsSource::RespondWithCrashIds, base::Unretained(this), callback));
if (pending_crash_list_loading_)
return;
pending_crash_list_loading_ = true;
crash_upload_list_->Load(base::BindOnce(
&CrashIdsSource::OnUploadListAvailable, base::Unretained(this)));
}
void CrashIdsSource::OnUploadListAvailable() {
pending_crash_list_loading_ = false;
// Only get the IDs of crashes that occurred within the last hour (if any).
std::vector<UploadList::UploadInfo> crashes;
crash_upload_list_->GetUploads(kMaxCrashesCountToRetrieve, &crashes);
const base::Time now = base::Time::Now();
crash_ids_list_.clear();
crash_ids_list_.reserve(kMaxCrashesCountToRetrieve *
(kCrashIdStringSize + 2));
// The feedback server expects the crash IDs to be a comma-separated list.
for (const auto& crash_info : crashes) {
const base::Time& report_time =
crash_info.state == UploadList::UploadInfo::State::Uploaded
? crash_info.upload_time
: crash_info.capture_time;
if (now - report_time < kOneHourTimeDelta) {
const std::string& crash_id = crash_info.upload_id;
crash_ids_list_.append(crash_ids_list_.empty() ? crash_id
: ", " + crash_id);
}
}
for (const auto& request : pending_requests_)
request.Run();
pending_requests_.clear();
}
void CrashIdsSource::RespondWithCrashIds(
const SysLogsSourceCallback& callback) const {
std::unique_ptr<SystemLogsResponse> response(new SystemLogsResponse());
(*response)[feedback::FeedbackReport::kCrashReportIdsKey] = crash_ids_list_;
// We must respond anyways.
callback.Run(response.get());
}
} // namespace system_logs