crash_upload_list.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/crash_upload_list.h"
6
7#include <algorithm>
8#include <iterator>
9
10#include "base/bind.h"
11#include "base/file_util.h"
12#include "base/files/file_path.h"
13#include "base/path_service.h"
14#include "base/strings/string_number_conversions.h"
15#include "base/strings/string_split.h"
16#if defined(OS_WIN)
17#include "chrome/browser/crash_upload_list_win.h"
18#endif
19#include "components/breakpad/common/breakpad_paths.h"
20#include "content/public/browser/browser_thread.h"
21
22using content::BrowserThread;
23
24CrashUploadList::CrashInfo::CrashInfo(const std::string& c, const base::Time& t)
25    : crash_id(c), crash_time(t) {}
26
27CrashUploadList::CrashInfo::~CrashInfo() {}
28
29// static
30CrashUploadList* CrashUploadList::Create(Delegate* delegate) {
31#if defined(OS_WIN)
32  return new CrashUploadListWin(delegate);
33#else
34  return new CrashUploadList(delegate);
35#endif
36}
37
38// static
39const char* CrashUploadList::kReporterLogFilename = "uploads.log";
40
41CrashUploadList::CrashUploadList(Delegate* delegate) : delegate_(delegate) {}
42
43CrashUploadList::~CrashUploadList() {}
44
45void CrashUploadList::LoadCrashListAsynchronously() {
46  BrowserThread::PostBlockingPoolTask(
47      FROM_HERE,
48      base::Bind(&CrashUploadList::LoadCrashListAndInformDelegateOfCompletion,
49                 this));
50}
51
52void CrashUploadList::ClearDelegate() {
53  delegate_ = NULL;
54}
55
56
57void CrashUploadList::LoadCrashListAndInformDelegateOfCompletion() {
58  LoadCrashList();
59  BrowserThread::PostTask(
60      BrowserThread::UI,
61      FROM_HERE,
62      base::Bind(&CrashUploadList::InformDelegateOfCompletion, this));
63}
64
65void CrashUploadList::LoadCrashList() {
66  base::FilePath crash_dir_path;
67  PathService::Get(breakpad::DIR_CRASH_DUMPS, &crash_dir_path);
68  base::FilePath upload_log_path = crash_dir_path.AppendASCII("uploads.log");
69  if (file_util::PathExists(upload_log_path)) {
70    std::string contents;
71    file_util::ReadFileToString(upload_log_path, &contents);
72    std::vector<std::string> log_entries;
73    base::SplitStringAlongWhitespace(contents, &log_entries);
74    ParseLogEntries(log_entries);
75  }
76}
77
78void CrashUploadList::ParseLogEntries(
79    const std::vector<std::string>& log_entries) {
80  std::vector<std::string>::const_reverse_iterator i;
81  for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) {
82    std::vector<std::string> components;
83    base::SplitString(*i, ',', &components);
84    // Skip any blank (or corrupted) lines.
85    if (components.size() != 2)
86      continue;
87    double seconds_since_epoch;
88    if (!base::StringToDouble(components[0], &seconds_since_epoch))
89      continue;
90    CrashInfo info(components[1], base::Time::FromDoubleT(seconds_since_epoch));
91    crashes_.push_back(info);
92  }
93}
94
95void CrashUploadList::InformDelegateOfCompletion() {
96  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97  if (delegate_)
98    delegate_->OnCrashListAvailable();
99}
100
101void CrashUploadList::GetUploadedCrashes(unsigned int max_count,
102                                         std::vector<CrashInfo>* crashes) {
103  std::copy(crashes_.begin(),
104            crashes_.begin() + std::min<size_t>(crashes_.size(), max_count),
105            std::back_inserter(*crashes));
106}
107
108std::vector<CrashUploadList::CrashInfo>& CrashUploadList::crashes() {
109  return crashes_;
110}
111