blob: 082c01dfa059008f9e9239653e872922b0d55823 [file] [log] [blame]
[email protected]9e94ab772013-07-23 08:00:571// Copyright 2013 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
sdefresne44eb1f22015-08-06 08:51:555#include "components/upload_list/upload_list.h"
[email protected]9e94ab772013-07-23 08:00:576
7#include <algorithm>
8#include <iterator>
rsesek622175192016-03-28 15:41:389#include <utility>
[email protected]9e94ab772013-07-23 08:00:5710
11#include "base/bind.h"
thestig18dfb7a52014-08-26 10:44:0412#include "base/files/file_util.h"
sdefresne44eb1f22015-08-06 08:51:5513#include "base/location.h"
gab9954e8c2016-09-15 21:28:4414#include "base/sequenced_task_runner.h"
[email protected]9e94ab772013-07-23 08:00:5715#include "base/strings/string_number_conversions.h"
16#include "base/strings/string_split.h"
brettw83dc1612015-08-12 07:31:1817#include "base/strings/string_util.h"
gab9954e8c2016-09-15 21:28:4418#include "base/task_runner.h"
19#include "base/threading/sequenced_task_runner_handle.h"
[email protected]9e94ab772013-07-23 08:00:5720
grunellb452aa32015-10-23 07:21:0921UploadList::UploadInfo::UploadInfo(const std::string& upload_id,
22 const base::Time& upload_time,
23 const std::string& local_id,
scottmg6d5a71f2016-06-21 04:18:5124 const base::Time& capture_time,
25 State state)
26 : upload_id(upload_id),
27 upload_time(upload_time),
28 local_id(local_id),
29 capture_time(capture_time),
30 state(state) {}
[email protected]25021cfb2014-03-25 17:20:3531
gayanecc7d54e2016-09-14 16:53:4932UploadList::UploadInfo::UploadInfo(const std::string& local_id,
33 const base::Time& capture_time,
34 State state,
35 const base::string16& file_size)
36 : local_id(local_id),
37 capture_time(capture_time),
38 state(state),
39 file_size(file_size) {}
40
grunellb452aa32015-10-23 07:21:0941UploadList::UploadInfo::UploadInfo(const std::string& upload_id,
42 const base::Time& upload_time)
scottmg6d5a71f2016-06-21 04:18:5143 : upload_id(upload_id), upload_time(upload_time), state(State::Uploaded) {}
[email protected]9e94ab772013-07-23 08:00:5744
gayanecc7d54e2016-09-14 16:53:4945UploadList::UploadInfo::UploadInfo(const UploadInfo& upload_info)
46 : upload_id(upload_info.upload_id),
47 upload_time(upload_info.upload_time),
48 local_id(upload_info.local_id),
49 capture_time(upload_info.capture_time),
50 state(upload_info.state),
51 file_size(upload_info.file_size) {}
52
gab9954e8c2016-09-15 21:28:4453UploadList::UploadInfo::~UploadInfo() = default;
[email protected]9e94ab772013-07-23 08:00:5754
gab9954e8c2016-09-15 21:28:4455UploadList::UploadList(Delegate* delegate,
56 const base::FilePath& upload_log_path,
57 scoped_refptr<base::TaskRunner> task_runner)
[email protected]9e94ab772013-07-23 08:00:5758 : delegate_(delegate),
sdefresne44eb1f22015-08-06 08:51:5559 upload_log_path_(upload_log_path),
gab9954e8c2016-09-15 21:28:4460 task_runner_(std::move(task_runner)) {}
[email protected]9e94ab772013-07-23 08:00:5761
gab9954e8c2016-09-15 21:28:4462UploadList::~UploadList() = default;
[email protected]9e94ab772013-07-23 08:00:5763
64void UploadList::LoadUploadListAsynchronously() {
gab9954e8c2016-09-15 21:28:4465 DCHECK(sequence_checker_.CalledOnValidSequence());
66 task_runner_->PostTask(
67 FROM_HERE, base::Bind(&UploadList::PerformLoadAndNotifyDelegate, this,
68 base::SequencedTaskRunnerHandle::Get()));
[email protected]9e94ab772013-07-23 08:00:5769}
70
71void UploadList::ClearDelegate() {
gab9954e8c2016-09-15 21:28:4472 DCHECK(sequence_checker_.CalledOnValidSequence());
[email protected]9e94ab772013-07-23 08:00:5773 delegate_ = NULL;
74}
75
rsesek622175192016-03-28 15:41:3876void UploadList::PerformLoadAndNotifyDelegate(
gab9954e8c2016-09-15 21:28:4477 scoped_refptr<base::SequencedTaskRunner> task_runner) {
rsesek622175192016-03-28 15:41:3878 std::vector<UploadInfo> uploads;
79 LoadUploadList(&uploads);
sdefresne44eb1f22015-08-06 08:51:5580 task_runner->PostTask(
[email protected]9e94ab772013-07-23 08:00:5781 FROM_HERE,
rsesek622175192016-03-28 15:41:3882 base::Bind(&UploadList::SetUploadsAndNotifyDelegate, this,
83 std::move(uploads)));
[email protected]9e94ab772013-07-23 08:00:5784}
85
rsesek622175192016-03-28 15:41:3886void UploadList::LoadUploadList(std::vector<UploadInfo>* uploads) {
[email protected]9e94ab772013-07-23 08:00:5787 if (base::PathExists(upload_log_path_)) {
88 std::string contents;
[email protected]82f84b92013-08-30 18:23:5089 base::ReadFileToString(upload_log_path_, &contents);
brettw83dc1612015-08-12 07:31:1890 std::vector<std::string> log_entries = base::SplitString(
91 contents, base::kWhitespaceASCII, base::KEEP_WHITESPACE,
92 base::SPLIT_WANT_NONEMPTY);
rsesek622175192016-03-28 15:41:3893 ParseLogEntries(log_entries, uploads);
[email protected]9e94ab772013-07-23 08:00:5794 }
95}
96
gayane2da65732016-09-07 22:19:3297const base::FilePath& UploadList::upload_log_path() const {
98 return upload_log_path_;
99}
100
[email protected]9e94ab772013-07-23 08:00:57101void UploadList::ParseLogEntries(
rsesek622175192016-03-28 15:41:38102 const std::vector<std::string>& log_entries,
103 std::vector<UploadInfo>* uploads) {
[email protected]9e94ab772013-07-23 08:00:57104 std::vector<std::string>::const_reverse_iterator i;
105 for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) {
brettwc6f82b12015-07-21 21:37:38106 std::vector<std::string> components = base::SplitString(
107 *i, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]9e94ab772013-07-23 08:00:57108 // Skip any blank (or corrupted) lines.
scottmg6d5a71f2016-06-21 04:18:51109 if (components.size() < 2 || components.size() > 5)
[email protected]9e94ab772013-07-23 08:00:57110 continue;
[email protected]25021cfb2014-03-25 17:20:35111 base::Time upload_time;
[email protected]9e94ab772013-07-23 08:00:57112 double seconds_since_epoch;
[email protected]25021cfb2014-03-25 17:20:35113 if (!components[0].empty()) {
114 if (!base::StringToDouble(components[0], &seconds_since_epoch))
115 continue;
116 upload_time = base::Time::FromDoubleT(seconds_since_epoch);
117 }
118 UploadInfo info(components[1], upload_time);
grunellb452aa32015-10-23 07:21:09119
120 // Add local ID if present.
121 if (components.size() > 2)
[email protected]25021cfb2014-03-25 17:20:35122 info.local_id = components[2];
grunellb452aa32015-10-23 07:21:09123
124 // Add capture time if present.
125 if (components.size() > 3 &&
126 !components[3].empty() &&
127 base::StringToDouble(components[3], &seconds_since_epoch)) {
128 info.capture_time = base::Time::FromDoubleT(seconds_since_epoch);
129 }
130
scottmg6d5a71f2016-06-21 04:18:51131 int state;
132 if (components.size() > 4 &&
133 !components[4].empty() &&
134 base::StringToInt(components[4], &state)) {
135 info.state = static_cast<UploadInfo::State>(state);
136 }
137
rsesek622175192016-03-28 15:41:38138 uploads->push_back(info);
[email protected]9e94ab772013-07-23 08:00:57139 }
140}
141
rsesek622175192016-03-28 15:41:38142void UploadList::SetUploadsAndNotifyDelegate(std::vector<UploadInfo> uploads) {
gab9954e8c2016-09-15 21:28:44143 DCHECK(sequence_checker_.CalledOnValidSequence());
rsesek622175192016-03-28 15:41:38144 uploads_ = std::move(uploads);
[email protected]9e94ab772013-07-23 08:00:57145 if (delegate_)
146 delegate_->OnUploadListAvailable();
147}
148
rsesek622175192016-03-28 15:41:38149void UploadList::GetUploads(size_t max_count,
[email protected]9e94ab772013-07-23 08:00:57150 std::vector<UploadInfo>* uploads) {
gab9954e8c2016-09-15 21:28:44151 DCHECK(sequence_checker_.CalledOnValidSequence());
[email protected]9e94ab772013-07-23 08:00:57152 std::copy(uploads_.begin(),
rsesek622175192016-03-28 15:41:38153 uploads_.begin() + std::min(uploads_.size(), max_count),
[email protected]9e94ab772013-07-23 08:00:57154 std::back_inserter(*uploads));
155}
gayanef132d5d2016-09-07 16:07:10156
157void UploadList::RequestSingleCrashUploadAsync(const std::string& local_id) {
gab9954e8c2016-09-15 21:28:44158 DCHECK(sequence_checker_.CalledOnValidSequence());
gab9954e8c2016-09-15 21:28:44159 task_runner_->PostTask(
gayanef132d5d2016-09-07 16:07:10160 FROM_HERE,
161 base::Bind(&UploadList::RequestSingleCrashUpload, this, local_id));
gayanef132d5d2016-09-07 16:07:10162}
163
164void UploadList::RequestSingleCrashUpload(const std::string& local_id) {
isherman4fb2ead2016-09-22 01:21:33165 // Manual uploads for not-yet uploaded crash reports are only available for
166 // Crashpad systems and for Android.
gayanef132d5d2016-09-07 16:07:10167 NOTREACHED();
168}