1 // 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 5 #include "chrome/browser/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/strings/string_number_conversions.h" 13 #include "base/strings/string_split.h" 14 #include "content/public/browser/browser_thread.h" 15 16 using content::BrowserThread; 17 18 UploadList::UploadInfo::UploadInfo(const std::string& id, 19 const base::Time& t, 20 const std::string& local_id) 21 : id(id), time(t), local_id(local_id) {} 22 23 UploadList::UploadInfo::UploadInfo(const std::string& id, const base::Time& t) 24 : id(id), time(t) {} 25 26 UploadList::UploadInfo::~UploadInfo() {} 27 28 UploadList::UploadList(Delegate* delegate, 29 const base::FilePath& upload_log_path) 30 : delegate_(delegate), 31 upload_log_path_(upload_log_path) {} 32 33 UploadList::~UploadList() {} 34 35 void UploadList::LoadUploadListAsynchronously() { 36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 37 BrowserThread::PostBlockingPoolTask( 38 FROM_HERE, 39 base::Bind(&UploadList::LoadUploadListAndInformDelegateOfCompletion, 40 this)); 41 } 42 43 void UploadList::ClearDelegate() { 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 45 delegate_ = NULL; 46 } 47 48 void UploadList::LoadUploadListAndInformDelegateOfCompletion() { 49 LoadUploadList(); 50 BrowserThread::PostTask( 51 BrowserThread::UI, 52 FROM_HERE, 53 base::Bind(&UploadList::InformDelegateOfCompletion, this)); 54 } 55 56 void UploadList::LoadUploadList() { 57 if (base::PathExists(upload_log_path_)) { 58 std::string contents; 59 base::ReadFileToString(upload_log_path_, &contents); 60 std::vector<std::string> log_entries; 61 base::SplitStringAlongWhitespace(contents, &log_entries); 62 ClearUploads(); 63 ParseLogEntries(log_entries); 64 } 65 } 66 67 void UploadList::AppendUploadInfo(const UploadInfo& info) { 68 uploads_.push_back(info); 69 } 70 71 void UploadList::ClearUploads() { 72 uploads_.clear(); 73 } 74 75 void UploadList::ParseLogEntries( 76 const std::vector<std::string>& log_entries) { 77 std::vector<std::string>::const_reverse_iterator i; 78 for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) { 79 std::vector<std::string> components; 80 base::SplitString(*i, ',', &components); 81 // Skip any blank (or corrupted) lines. 82 if (components.size() != 2 && components.size() != 3) 83 continue; 84 base::Time upload_time; 85 double seconds_since_epoch; 86 if (!components[0].empty()) { 87 if (!base::StringToDouble(components[0], &seconds_since_epoch)) 88 continue; 89 upload_time = base::Time::FromDoubleT(seconds_since_epoch); 90 } 91 UploadInfo info(components[1], upload_time); 92 if (components.size() == 3) 93 info.local_id = components[2]; 94 uploads_.push_back(info); 95 } 96 } 97 98 void UploadList::InformDelegateOfCompletion() { 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 100 if (delegate_) 101 delegate_->OnUploadListAvailable(); 102 } 103 104 void UploadList::GetUploads(unsigned int max_count, 105 std::vector<UploadInfo>* uploads) { 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 107 std::copy(uploads_.begin(), 108 uploads_.begin() + std::min<size_t>(uploads_.size(), max_count), 109 std::back_inserter(*uploads)); 110 } 111