1 // Copyright 2014 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 "components/feedback/feedback_report.h" 6 7 #include "base/file_util.h" 8 #include "base/files/file.h" 9 #include "base/files/file_enumerator.h" 10 #include "base/files/important_file_writer.h" 11 #include "base/guid.h" 12 #include "base/sequenced_task_runner.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/threading/sequenced_worker_pool.h" 15 16 namespace { 17 18 const base::FilePath::CharType kFeedbackReportFilenameWildcard[] = 19 FILE_PATH_LITERAL("Feedback Report.*"); 20 21 const char kFeedbackReportFilenamePrefix[] = "Feedback Report."; 22 23 void WriteReportOnBlockingPool(const base::FilePath reports_path, 24 const base::FilePath& file, 25 const std::string& data) { 26 DCHECK(reports_path.IsParent(file)); 27 if (!base::DirectoryExists(reports_path)) { 28 base::File::Error error; 29 if (!base::CreateDirectoryAndGetError(reports_path, &error)) 30 return; 31 } 32 base::ImportantFileWriter::WriteFileAtomically(file, data); 33 } 34 35 } // namespace 36 37 namespace feedback { 38 39 FeedbackReport::FeedbackReport( 40 const base::FilePath& path, 41 const base::Time& upload_at, 42 const std::string& data, 43 scoped_refptr<base::SequencedTaskRunner> task_runner) 44 : reports_path_(path), 45 upload_at_(upload_at), 46 data_(data), 47 reports_task_runner_(task_runner) { 48 if (reports_path_.empty()) 49 return; 50 file_ = reports_path_.AppendASCII( 51 kFeedbackReportFilenamePrefix + base::GenerateGUID()); 52 53 reports_task_runner_->PostTask(FROM_HERE, base::Bind( 54 &WriteReportOnBlockingPool, reports_path_, file_, data_)); 55 } 56 57 FeedbackReport::~FeedbackReport() {} 58 59 void FeedbackReport::DeleteReportOnDisk() { 60 reports_task_runner_->PostTask(FROM_HERE, base::Bind( 61 base::IgnoreResult(&base::DeleteFile), file_, false)); 62 } 63 64 // static 65 void FeedbackReport::LoadReportsAndQueue( 66 const base::FilePath& user_dir, QueueCallback callback) { 67 if (user_dir.empty()) 68 return; 69 70 base::FileEnumerator enumerator(user_dir, 71 false, 72 base::FileEnumerator::FILES, 73 kFeedbackReportFilenameWildcard); 74 for (base::FilePath name = enumerator.Next(); 75 !name.empty(); 76 name = enumerator.Next()) { 77 std::string data; 78 if (ReadFileToString(name, &data)) 79 callback.Run(data); 80 base::DeleteFile(name, false); 81 } 82 } 83 84 } // namespace feedback 85