feedback_data.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. #include "components/feedback/feedback_data.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/files/file_util.h"
  8. #include "base/json/json_string_value_serializer.h"
  9. #include "base/memory/ref_counted_memory.h"
  10. #include "base/strings/string_util.h"
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "base/task/thread_pool.h"
  13. #include "base/values.h"
  14. #include "components/feedback/feedback_util.h"
  15. #include "components/feedback/proto/extension.pb.h"
  16. #include "components/feedback/tracing_manager.h"
  17. namespace feedback {
  18. namespace {
  19. const char kTraceFilename[] = "tracing.zip";
  20. const char kPerformanceCategoryTag[] = "Performance";
  21. const base::FilePath::CharType kHistogramsFilename[] =
  22. FILE_PATH_LITERAL("histograms.txt");
  23. const char kHistogramsAttachmentName[] = "histograms.zip";
  24. } // namespace
  25. FeedbackData::FeedbackData(base::WeakPtr<feedback::FeedbackUploader> uploader,
  26. TracingManager* tracing_manager)
  27. : uploader_(std::move(uploader)), tracing_manager_(tracing_manager) {}
  28. FeedbackData::~FeedbackData() = default;
  29. void FeedbackData::OnFeedbackPageDataComplete() {
  30. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  31. pending_op_count_--;
  32. SendReport();
  33. }
  34. void FeedbackData::CompressSystemInfo() {
  35. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  36. if (trace_id_ != 0) {
  37. ++pending_op_count_;
  38. if (!tracing_manager_ ||
  39. !tracing_manager_->GetTraceData(
  40. trace_id_,
  41. base::BindOnce(&FeedbackData::OnGetTraceData, this, trace_id_))) {
  42. pending_op_count_--;
  43. trace_id_ = 0;
  44. }
  45. }
  46. ++pending_op_count_;
  47. base::ThreadPool::PostTaskAndReply(
  48. FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
  49. base::BindOnce(&FeedbackData::CompressLogs, this),
  50. base::BindOnce(&FeedbackData::OnCompressComplete, this));
  51. }
  52. void FeedbackData::SetAndCompressHistograms(std::string histograms) {
  53. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  54. ++pending_op_count_;
  55. base::ThreadPool::PostTaskAndReply(
  56. FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
  57. base::BindOnce(&FeedbackData::CompressFile, this,
  58. base::FilePath(kHistogramsFilename),
  59. kHistogramsAttachmentName, std::move(histograms)),
  60. base::BindOnce(&FeedbackData::OnCompressComplete, this));
  61. }
  62. void FeedbackData::AttachAndCompressFileData(std::string attached_filedata) {
  63. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  64. if (attached_filedata.empty())
  65. return;
  66. ++pending_op_count_;
  67. base::FilePath attached_file =
  68. base::FilePath::FromUTF8Unsafe(attached_filename_);
  69. base::ThreadPool::PostTaskAndReply(
  70. FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
  71. base::BindOnce(&FeedbackData::CompressFile, this, attached_file,
  72. std::string(), std::move(attached_filedata)),
  73. base::BindOnce(&FeedbackData::OnCompressComplete, this));
  74. }
  75. void FeedbackData::OnGetTraceData(
  76. int trace_id,
  77. scoped_refptr<base::RefCountedString> trace_data) {
  78. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  79. if (tracing_manager_)
  80. tracing_manager_->DiscardTraceData(trace_id);
  81. AddFile(kTraceFilename, std::move(trace_data->data()));
  82. set_category_tag(kPerformanceCategoryTag);
  83. --pending_op_count_;
  84. trace_id_ = 0;
  85. SendReport();
  86. }
  87. void FeedbackData::OnCompressComplete() {
  88. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  89. --pending_op_count_;
  90. SendReport();
  91. }
  92. bool FeedbackData::IsDataComplete() {
  93. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  94. return pending_op_count_ == 0;
  95. }
  96. void FeedbackData::SendReport() {
  97. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  98. if (uploader_ && IsDataComplete() && !report_sent_) {
  99. report_sent_ = true;
  100. userfeedback::ExtensionSubmit feedback_data;
  101. PrepareReport(&feedback_data);
  102. auto post_body = std::make_unique<std::string>();
  103. feedback_data.SerializeToString(post_body.get());
  104. uploader_->QueueReport(std::move(post_body),
  105. /*has_email=*/!user_email().empty());
  106. }
  107. }
  108. } // namespace feedback