report_queue_provider.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2021 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. #ifndef COMPONENTS_REPORTING_CLIENT_REPORT_QUEUE_PROVIDER_H_
  5. #define COMPONENTS_REPORTING_CLIENT_REPORT_QUEUE_PROVIDER_H_
  6. #include <memory>
  7. #include <queue>
  8. #include <utility>
  9. #include "base/callback.h"
  10. #include "base/feature_list.h"
  11. #include "base/memory/ref_counted.h"
  12. #include "base/memory/scoped_refptr.h"
  13. #include "base/task/sequenced_task_runner.h"
  14. #include "components/reporting/client/report_queue.h"
  15. #include "components/reporting/client/report_queue_configuration.h"
  16. #include "components/reporting/proto/synced/record_constants.pb.h"
  17. #include "components/reporting/storage/storage_module_interface.h"
  18. #include "components/reporting/util/status.h"
  19. #include "components/reporting/util/statusor.h"
  20. namespace reporting {
  21. // ReportQueueProvider acts a single point for instantiating
  22. // |reporting::ReportQueue|s. By performing initialization atomically it ensures
  23. // that all ReportQueues are created with the same global settings.
  24. //
  25. // In order to utilize the ReportQueueProvider the EncryptedReportingPipeline
  26. // feature must be turned on using --enable-features=EncryptedReportingPipeline.
  27. //
  28. // ReportQueueProvider is a singleton which can be accessed through
  29. // |ReportQueueProvider::GetInstance|. This static method must be implemented
  30. // for a specific configuration - Chrome (for ChromeOS and for other OSes),
  31. // other ChromeOS executables.
  32. //
  33. // Example Usage:
  34. // void SendMessage(google::protobuf::ImportantMessage important_message,
  35. // reporting::ReportQueue::EnqueueCallback done_cb) {
  36. // // Create configuration.
  37. // auto config_result = reporting::ReportQueueConfiguration::Create(...);
  38. // // Bail out if configuration failed to create.
  39. // if (!config_result.ok()) {
  40. // std::move(done_cb).Run(config_result.status());
  41. // return;
  42. // }
  43. // // Asynchronously create ReportingQueue.
  44. // base::ThreadPool::PostTask(
  45. // FROM_HERE,
  46. // base::BindOnce(
  47. // [](google::protobuf::ImportantMessage important_message,
  48. // reporting::ReportQueue::EnqueueCallback done_cb,
  49. // std::unique_ptr<reporting::ReportQueueConfiguration> config) {
  50. // // Asynchronously create ReportingQueue.
  51. // reporting::ReportQueueProvider::CreateQueue(
  52. // std::move(config),
  53. // base::BindOnce(
  54. // [](base::StringPiece data,
  55. // reporting::ReportQueue::EnqueueCallback
  56. // done_cb, reporting::StatusOr<std::unique_ptr<
  57. // reporting::ReportQueue>>
  58. // report_queue_result) {
  59. // // Bail out if queue failed to create.
  60. // if (!report_queue_result.ok()) {
  61. // std::move(done_cb).Run(report_queue_result.status());
  62. // return;
  63. // }
  64. // // Queue created successfully, enqueue the message.
  65. // report_queue_result.ValueOrDie()->Enqueue(
  66. // important_message, std::move(done_cb));
  67. // },
  68. // important_message, std::move(done_cb)));
  69. // },
  70. // important_message, std::move(done_cb),
  71. // std::move(config_result.ValueOrDie())))
  72. // }
  73. class ReportQueueProvider {
  74. public:
  75. using CreateReportQueueResponse = StatusOr<std::unique_ptr<ReportQueue>>;
  76. // The response will come back utilizing the ReportQueueProvider's thread. It
  77. // is likely that within Chromium you will want to the response to come back
  78. // on your own thread. The simplest way to achieve that is to pass a
  79. // base::BindPostTask rather than a base::OnceCallback. Another way to achieve
  80. // the same result is to utilize base::OnceCallback, and capture the response
  81. // and forward it to your own thread. We maintain base::OnceCallback here for
  82. // use in ChromiumOS.
  83. using CreateReportQueueCallback =
  84. base::OnceCallback<void(CreateReportQueueResponse)>;
  85. using OnStorageModuleCreatedCallback =
  86. base::OnceCallback<void(StatusOr<scoped_refptr<StorageModuleInterface>>)>;
  87. using StorageModuleCreateCallback =
  88. base::RepeatingCallback<void(OnStorageModuleCreatedCallback)>;
  89. // Callback triggered with updated report queue config after it has been
  90. // configured with appropriate DM tokens after it is retrieved. Typically,
  91. // this is when we go ahead and create the report queue.
  92. using ReportQueueConfiguredCallback = base::OnceCallback<void(
  93. StatusOr<std::unique_ptr<ReportQueueConfiguration>>)>;
  94. static const base::Feature kEncryptedReportingPipeline;
  95. explicit ReportQueueProvider(StorageModuleCreateCallback storage_create_cb);
  96. ReportQueueProvider(const ReportQueueProvider& other) = delete;
  97. ReportQueueProvider& operator=(const ReportQueueProvider& other) = delete;
  98. virtual ~ReportQueueProvider();
  99. // Asynchronously creates a queue based on the configuration. In the process
  100. // singleton ReportQueueProvider is potentially created and retrieved
  101. // internally, and then started to initialize (if initialization fails,
  102. // |CreateQueue| will return with error, but next attempt may succeed).
  103. // Returns with the callback handing ownership to the caller (unless there is
  104. // an error, and then it gets the error status).
  105. static void CreateQueue(std::unique_ptr<ReportQueueConfiguration> config,
  106. CreateReportQueueCallback queue_cb);
  107. // Synchronously creates a speculative queue based on the configuration.
  108. // Returns result as a smart pointer to ReportQueue with the on-thread
  109. // deleter.
  110. static StatusOr<std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter>>
  111. CreateSpeculativeQueue(std::unique_ptr<ReportQueueConfiguration> config);
  112. // Instantiates ReportQueueProvider singleton based on the overall process
  113. // state and will refer to StorageModuleInterface and optional Uploader
  114. // accordingly.
  115. static ReportQueueProvider* GetInstance();
  116. static bool IsEncryptedReportingPipelineEnabled();
  117. // Accessors.
  118. base::WeakPtr<ReportQueueProvider> GetWeakPtr();
  119. scoped_refptr<StorageModuleInterface> storage() const;
  120. scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner() const;
  121. // Storage module creator (can be substituted for testing purposes).
  122. StorageModuleCreateCallback storage_create_cb_;
  123. private:
  124. // Holds the creation request for a ReportQueue.
  125. class CreateReportQueueRequest;
  126. // Finalizes provider, if the initialization process succeeded.
  127. // May to be overridden by subclass to make more updates to the provider.
  128. virtual void OnInitCompleted();
  129. // Creates and initializes queue implementation. Returns status in case of
  130. // error.
  131. virtual void CreateNewQueue(std::unique_ptr<ReportQueueConfiguration> config,
  132. CreateReportQueueCallback cb);
  133. virtual StatusOr<std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter>>
  134. CreateNewSpeculativeQueue();
  135. // Configures a given report queue config with appropriate DM tokens after its
  136. // retrieval so it can be used for downstream processing while building a
  137. // report queue, and triggers the corresponding completion callback with the
  138. // updated config.
  139. virtual void ConfigureReportQueue(
  140. std::unique_ptr<ReportQueueConfiguration> report_queue_config,
  141. ReportQueueConfiguredCallback completion_cb) = 0;
  142. // Checks whether the provider has been initialized, and if so, processes all
  143. // pending queue creation requests.
  144. void CheckInitializationState();
  145. // Processes storage or error returned by async call to `storage_create_cb_`.
  146. void OnStorageModuleConfigured(
  147. StatusOr<scoped_refptr<StorageModuleInterface>> storage_result);
  148. // Task runner used for guarding the provider elements.
  149. scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
  150. SEQUENCE_CHECKER(sequence_checker_);
  151. // Queue for storing creation requests while the provider is
  152. // initializing.
  153. std::queue<std::unique_ptr<CreateReportQueueRequest>> create_request_queue_
  154. GUARDED_BY_CONTEXT(sequence_checker_);
  155. // Storage module associated with the provider. It serves all queues created
  156. // by it. `storage_` is null initially and when it becomes non-null, the
  157. // provider is ready to create actual queues (speculative queues can be
  158. // created before that as well).
  159. scoped_refptr<StorageModuleInterface> storage_
  160. GUARDED_BY_CONTEXT(sequence_checker_);
  161. // Weak pointer factory.
  162. base::WeakPtrFactory<ReportQueueProvider> weak_ptr_factory_{this};
  163. };
  164. } // namespace reporting
  165. #endif // COMPONENTS_REPORTING_CLIENT_REPORT_QUEUE_PROVIDER_H_