1 // Copyright (c) 2011 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 <iterator> 8 9 #include "base/path_service.h" 10 #include "base/file_path.h" 11 #include "base/file_util.h" 12 #include "base/string_number_conversions.h" 13 #include "base/string_split.h" 14 #if defined(OS_WIN) 15 #include "chrome/browser/crash_upload_list_win.h" 16 #endif 17 #include "chrome/common/chrome_paths.h" 18 #include "content/browser/browser_thread.h" 19 20 CrashUploadList::CrashInfo::CrashInfo(const std::string& c, const base::Time& t) 21 : crash_id(c), crash_time(t) {} 22 23 CrashUploadList::CrashInfo::~CrashInfo() {} 24 25 // static 26 CrashUploadList* CrashUploadList::Create(Delegate* delegate) { 27 #if defined(OS_WIN) 28 return new CrashUploadListWin(delegate); 29 #else 30 return new CrashUploadList(delegate); 31 #endif 32 } 33 34 CrashUploadList::CrashUploadList(Delegate* delegate) : delegate_(delegate) {} 35 36 CrashUploadList::~CrashUploadList() {} 37 38 void CrashUploadList::LoadCrashListAsynchronously() { 39 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 40 NewRunnableMethod(this, 41 &CrashUploadList::LoadCrashListAndInformDelegateOfCompletion)); 42 } 43 44 void CrashUploadList::ClearDelegate() { 45 delegate_ = NULL; 46 } 47 48 49 void CrashUploadList::LoadCrashListAndInformDelegateOfCompletion() { 50 LoadCrashList(); 51 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 52 NewRunnableMethod(this, &CrashUploadList::InformDelegateOfCompletion)); 53 } 54 55 void CrashUploadList::LoadCrashList() { 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 57 FilePath crash_dir_path; 58 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path); 59 FilePath upload_log_path = crash_dir_path.AppendASCII("uploads.log"); 60 if (file_util::PathExists(upload_log_path)) { 61 std::string contents; 62 file_util::ReadFileToString(upload_log_path, &contents); 63 std::vector<std::string> log_entries; 64 base::SplitStringAlongWhitespace(contents, &log_entries); 65 ParseLogEntries(log_entries); 66 } 67 } 68 69 void CrashUploadList::ParseLogEntries( 70 const std::vector<std::string>& log_entries) { 71 std::vector<std::string>::const_reverse_iterator i; 72 for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) { 73 std::vector<std::string> components; 74 base::SplitString(*i, ',', &components); 75 // Skip any blank (or corrupted) lines. 76 if (components.size() != 2) 77 continue; 78 double seconds_since_epoch; 79 if (!base::StringToDouble(components[0], &seconds_since_epoch)) 80 continue; 81 CrashInfo info(components[1], base::Time::FromDoubleT(seconds_since_epoch)); 82 crashes_.push_back(info); 83 } 84 } 85 86 void CrashUploadList::InformDelegateOfCompletion() { 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 88 if (delegate_) 89 delegate_->OnCrashListAvailable(); 90 } 91 92 void CrashUploadList::GetUploadedCrashes(unsigned int max_count, 93 std::vector<CrashInfo>* crashes) { 94 std::copy(crashes_.begin(), 95 crashes_.begin() + std::min<size_t>(crashes_.size(), max_count), 96 std::back_inserter(*crashes)); 97 } 98 99 std::vector<CrashUploadList::CrashInfo>& CrashUploadList::crashes() { 100 return crashes_; 101 } 102