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 20CrashUploadList::CrashInfo::CrashInfo(const std::string& c, const base::Time& t) 21 : crash_id(c), crash_time(t) {} 22 23CrashUploadList::CrashInfo::~CrashInfo() {} 24 25// static 26CrashUploadList* 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 34CrashUploadList::CrashUploadList(Delegate* delegate) : delegate_(delegate) {} 35 36CrashUploadList::~CrashUploadList() {} 37 38void CrashUploadList::LoadCrashListAsynchronously() { 39 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 40 NewRunnableMethod(this, 41 &CrashUploadList::LoadCrashListAndInformDelegateOfCompletion)); 42} 43 44void CrashUploadList::ClearDelegate() { 45 delegate_ = NULL; 46} 47 48 49void CrashUploadList::LoadCrashListAndInformDelegateOfCompletion() { 50 LoadCrashList(); 51 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 52 NewRunnableMethod(this, &CrashUploadList::InformDelegateOfCompletion)); 53} 54 55void 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 69void 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 86void CrashUploadList::InformDelegateOfCompletion() { 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 88 if (delegate_) 89 delegate_->OnCrashListAvailable(); 90} 91 92void 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 99std::vector<CrashUploadList::CrashInfo>& CrashUploadList::crashes() { 100 return crashes_; 101} 102