blob: b08d38f0d7ef0324570159425b9bba8315f3a4b2 [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"
[email protected]9e94ab772013-07-23 08:00:5714#include "base/strings/string_number_conversions.h"
15#include "base/strings/string_split.h"
brettw83dc1612015-08-12 07:31:1816#include "base/strings/string_util.h"
sdefresne44eb1f22015-08-06 08:51:5517#include "base/threading/sequenced_worker_pool.h"
gab7966d312016-05-11 20:35:0118#include "base/threading/thread_task_runner_handle.h"
[email protected]9e94ab772013-07-23 08:00:5719
grunellb452aa32015-10-23 07:21:0920UploadList::UploadInfo::UploadInfo(const std::string& upload_id,
21 const base::Time& upload_time,
22 const std::string& local_id,
scottmg6d5a71f2016-06-21 04:18:5123 const base::Time& capture_time,
24 State state)
25 : upload_id(upload_id),
26 upload_time(upload_time),
27 local_id(local_id),
28 capture_time(capture_time),
29 state(state) {}
[email protected]25021cfb2014-03-25 17:20:3530
gayanecc7d54e2016-09-14 16:53:4931UploadList::UploadInfo::UploadInfo(const std::string& local_id,
32 const base::Time& capture_time,
33 State state,
34 const base::string16& file_size)
35 : local_id(local_id),
36 capture_time(capture_time),
37 state(state),
38 file_size(file_size) {}
39
grunellb452aa32015-10-23 07:21:0940UploadList::UploadInfo::UploadInfo(const std::string& upload_id,
41 const base::Time& upload_time)
scottmg6d5a71f2016-06-21 04:18:5142 : upload_id(upload_id), upload_time(upload_time), state(State::Uploaded) {}
[email protected]9e94ab772013-07-23 08:00:5743
gayanecc7d54e2016-09-14 16:53:4944UploadList::UploadInfo::UploadInfo(const UploadInfo& upload_info)
45 : upload_id(upload_info.upload_id),
46 upload_time(upload_info.upload_time),
47 local_id(upload_info.local_id),
48 capture_time(upload_info.capture_time),
49 state(upload_info.state),
50 file_size(upload_info.file_size) {}
51
[email protected]9e94ab772013-07-23 08:00:5752UploadList::UploadInfo::~UploadInfo() {}
53
sdefresne44eb1f22015-08-06 08:51:5554UploadList::UploadList(
55 Delegate* delegate,
56 const base::FilePath& upload_log_path,
57 const scoped_refptr<base::SequencedWorkerPool>& worker_pool)
[email protected]9e94ab772013-07-23 08:00:5758 : delegate_(delegate),
sdefresne44eb1f22015-08-06 08:51:5559 upload_log_path_(upload_log_path),
60 worker_pool_(worker_pool) {}
[email protected]9e94ab772013-07-23 08:00:5761
62UploadList::~UploadList() {}
63
64void UploadList::LoadUploadListAsynchronously() {
sdefresne44eb1f22015-08-06 08:51:5565 DCHECK(thread_checker_.CalledOnValidThread());
66 worker_pool_->PostTask(
[email protected]9e94ab772013-07-23 08:00:5767 FROM_HERE,
rsesek622175192016-03-28 15:41:3868 base::Bind(&UploadList::PerformLoadAndNotifyDelegate,
sdefresne44eb1f22015-08-06 08:51:5569 this, base::ThreadTaskRunnerHandle::Get()));
[email protected]9e94ab772013-07-23 08:00:5770}
71
72void UploadList::ClearDelegate() {
sdefresne44eb1f22015-08-06 08:51:5573 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]9e94ab772013-07-23 08:00:5774 delegate_ = NULL;
75}
76
rsesek622175192016-03-28 15:41:3877void UploadList::PerformLoadAndNotifyDelegate(
sdefresne44eb1f22015-08-06 08:51:5578 const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
rsesek622175192016-03-28 15:41:3879 std::vector<UploadInfo> uploads;
80 LoadUploadList(&uploads);
sdefresne44eb1f22015-08-06 08:51:5581 task_runner->PostTask(
[email protected]9e94ab772013-07-23 08:00:5782 FROM_HERE,
rsesek622175192016-03-28 15:41:3883 base::Bind(&UploadList::SetUploadsAndNotifyDelegate, this,
84 std::move(uploads)));
[email protected]9e94ab772013-07-23 08:00:5785}
86
rsesek622175192016-03-28 15:41:3887void UploadList::LoadUploadList(std::vector<UploadInfo>* uploads) {
[email protected]9e94ab772013-07-23 08:00:5788 if (base::PathExists(upload_log_path_)) {
89 std::string contents;
[email protected]82f84b92013-08-30 18:23:5090 base::ReadFileToString(upload_log_path_, &contents);
brettw83dc1612015-08-12 07:31:1891 std::vector<std::string> log_entries = base::SplitString(
92 contents, base::kWhitespaceASCII, base::KEEP_WHITESPACE,
93 base::SPLIT_WANT_NONEMPTY);
rsesek622175192016-03-28 15:41:3894 ParseLogEntries(log_entries, uploads);
[email protected]9e94ab772013-07-23 08:00:5795 }
96}
97
gayane2da65732016-09-07 22:19:3298const base::FilePath& UploadList::upload_log_path() const {
99 return upload_log_path_;
100}
101
[email protected]9e94ab772013-07-23 08:00:57102void UploadList::ParseLogEntries(
rsesek622175192016-03-28 15:41:38103 const std::vector<std::string>& log_entries,
104 std::vector<UploadInfo>* uploads) {
[email protected]9e94ab772013-07-23 08:00:57105 std::vector<std::string>::const_reverse_iterator i;
106 for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) {
brettwc6f82b12015-07-21 21:37:38107 std::vector<std::string> components = base::SplitString(
108 *i, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
[email protected]9e94ab772013-07-23 08:00:57109 // Skip any blank (or corrupted) lines.
scottmg6d5a71f2016-06-21 04:18:51110 if (components.size() < 2 || components.size() > 5)
[email protected]9e94ab772013-07-23 08:00:57111 continue;
[email protected]25021cfb2014-03-25 17:20:35112 base::Time upload_time;
[email protected]9e94ab772013-07-23 08:00:57113 double seconds_since_epoch;
[email protected]25021cfb2014-03-25 17:20:35114 if (!components[0].empty()) {
115 if (!base::StringToDouble(components[0], &seconds_since_epoch))
116 continue;
117 upload_time = base::Time::FromDoubleT(seconds_since_epoch);
118 }
119 UploadInfo info(components[1], upload_time);
grunellb452aa32015-10-23 07:21:09120
121 // Add local ID if present.
122 if (components.size() > 2)
[email protected]25021cfb2014-03-25 17:20:35123 info.local_id = components[2];
grunellb452aa32015-10-23 07:21:09124
125 // Add capture time if present.
126 if (components.size() > 3 &&
127 !components[3].empty() &&
128 base::StringToDouble(components[3], &seconds_since_epoch)) {
129 info.capture_time = base::Time::FromDoubleT(seconds_since_epoch);
130 }
131
scottmg6d5a71f2016-06-21 04:18:51132 int state;
133 if (components.size() > 4 &&
134 !components[4].empty() &&
135 base::StringToInt(components[4], &state)) {
136 info.state = static_cast<UploadInfo::State>(state);
137 }
138
rsesek622175192016-03-28 15:41:38139 uploads->push_back(info);
[email protected]9e94ab772013-07-23 08:00:57140 }
141}
142
rsesek622175192016-03-28 15:41:38143void UploadList::SetUploadsAndNotifyDelegate(std::vector<UploadInfo> uploads) {
sdefresne44eb1f22015-08-06 08:51:55144 DCHECK(thread_checker_.CalledOnValidThread());
rsesek622175192016-03-28 15:41:38145 uploads_ = std::move(uploads);
[email protected]9e94ab772013-07-23 08:00:57146 if (delegate_)
147 delegate_->OnUploadListAvailable();
148}
149
rsesek622175192016-03-28 15:41:38150void UploadList::GetUploads(size_t max_count,
[email protected]9e94ab772013-07-23 08:00:57151 std::vector<UploadInfo>* uploads) {
sdefresne44eb1f22015-08-06 08:51:55152 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]9e94ab772013-07-23 08:00:57153 std::copy(uploads_.begin(),
rsesek622175192016-03-28 15:41:38154 uploads_.begin() + std::min(uploads_.size(), max_count),
[email protected]9e94ab772013-07-23 08:00:57155 std::back_inserter(*uploads));
156}
gayanef132d5d2016-09-07 16:07:10157
158void UploadList::RequestSingleCrashUploadAsync(const std::string& local_id) {
159#if defined(OS_WIN) || defined(OS_MACOSX)
160 DCHECK(thread_checker_.CalledOnValidThread());
161 worker_pool_->PostTask(
162 FROM_HERE,
163 base::Bind(&UploadList::RequestSingleCrashUpload, this, local_id));
164#endif
165}
166
167void UploadList::RequestSingleCrashUpload(const std::string& local_id) {
168 // Manual uploads for not uploaded crash reports are not available for non
169 // crashpad systems.
170 NOTREACHED();
171}