123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COMPONENTS_REPORTING_CLIENT_REPORT_QUEUE_PROVIDER_H_
- #define COMPONENTS_REPORTING_CLIENT_REPORT_QUEUE_PROVIDER_H_
- #include <memory>
- #include <queue>
- #include <utility>
- #include "base/callback.h"
- #include "base/feature_list.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/task/sequenced_task_runner.h"
- #include "components/reporting/client/report_queue.h"
- #include "components/reporting/client/report_queue_configuration.h"
- #include "components/reporting/proto/synced/record_constants.pb.h"
- #include "components/reporting/storage/storage_module_interface.h"
- #include "components/reporting/util/status.h"
- #include "components/reporting/util/statusor.h"
- namespace reporting {
- // ReportQueueProvider acts a single point for instantiating
- // |reporting::ReportQueue|s. By performing initialization atomically it ensures
- // that all ReportQueues are created with the same global settings.
- //
- // In order to utilize the ReportQueueProvider the EncryptedReportingPipeline
- // feature must be turned on using --enable-features=EncryptedReportingPipeline.
- //
- // ReportQueueProvider is a singleton which can be accessed through
- // |ReportQueueProvider::GetInstance|. This static method must be implemented
- // for a specific configuration - Chrome (for ChromeOS and for other OSes),
- // other ChromeOS executables.
- //
- // Example Usage:
- // void SendMessage(google::protobuf::ImportantMessage important_message,
- // reporting::ReportQueue::EnqueueCallback done_cb) {
- // // Create configuration.
- // auto config_result = reporting::ReportQueueConfiguration::Create(...);
- // // Bail out if configuration failed to create.
- // if (!config_result.ok()) {
- // std::move(done_cb).Run(config_result.status());
- // return;
- // }
- // // Asynchronously create ReportingQueue.
- // base::ThreadPool::PostTask(
- // FROM_HERE,
- // base::BindOnce(
- // [](google::protobuf::ImportantMessage important_message,
- // reporting::ReportQueue::EnqueueCallback done_cb,
- // std::unique_ptr<reporting::ReportQueueConfiguration> config) {
- // // Asynchronously create ReportingQueue.
- // reporting::ReportQueueProvider::CreateQueue(
- // std::move(config),
- // base::BindOnce(
- // [](base::StringPiece data,
- // reporting::ReportQueue::EnqueueCallback
- // done_cb, reporting::StatusOr<std::unique_ptr<
- // reporting::ReportQueue>>
- // report_queue_result) {
- // // Bail out if queue failed to create.
- // if (!report_queue_result.ok()) {
- // std::move(done_cb).Run(report_queue_result.status());
- // return;
- // }
- // // Queue created successfully, enqueue the message.
- // report_queue_result.ValueOrDie()->Enqueue(
- // important_message, std::move(done_cb));
- // },
- // important_message, std::move(done_cb)));
- // },
- // important_message, std::move(done_cb),
- // std::move(config_result.ValueOrDie())))
- // }
- class ReportQueueProvider {
- public:
- using CreateReportQueueResponse = StatusOr<std::unique_ptr<ReportQueue>>;
- // The response will come back utilizing the ReportQueueProvider's thread. It
- // is likely that within Chromium you will want to the response to come back
- // on your own thread. The simplest way to achieve that is to pass a
- // base::BindPostTask rather than a base::OnceCallback. Another way to achieve
- // the same result is to utilize base::OnceCallback, and capture the response
- // and forward it to your own thread. We maintain base::OnceCallback here for
- // use in ChromiumOS.
- using CreateReportQueueCallback =
- base::OnceCallback<void(CreateReportQueueResponse)>;
- using OnStorageModuleCreatedCallback =
- base::OnceCallback<void(StatusOr<scoped_refptr<StorageModuleInterface>>)>;
- using StorageModuleCreateCallback =
- base::RepeatingCallback<void(OnStorageModuleCreatedCallback)>;
- // Callback triggered with updated report queue config after it has been
- // configured with appropriate DM tokens after it is retrieved. Typically,
- // this is when we go ahead and create the report queue.
- using ReportQueueConfiguredCallback = base::OnceCallback<void(
- StatusOr<std::unique_ptr<ReportQueueConfiguration>>)>;
- static const base::Feature kEncryptedReportingPipeline;
- explicit ReportQueueProvider(StorageModuleCreateCallback storage_create_cb);
- ReportQueueProvider(const ReportQueueProvider& other) = delete;
- ReportQueueProvider& operator=(const ReportQueueProvider& other) = delete;
- virtual ~ReportQueueProvider();
- // Asynchronously creates a queue based on the configuration. In the process
- // singleton ReportQueueProvider is potentially created and retrieved
- // internally, and then started to initialize (if initialization fails,
- // |CreateQueue| will return with error, but next attempt may succeed).
- // Returns with the callback handing ownership to the caller (unless there is
- // an error, and then it gets the error status).
- static void CreateQueue(std::unique_ptr<ReportQueueConfiguration> config,
- CreateReportQueueCallback queue_cb);
- // Synchronously creates a speculative queue based on the configuration.
- // Returns result as a smart pointer to ReportQueue with the on-thread
- // deleter.
- static StatusOr<std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter>>
- CreateSpeculativeQueue(std::unique_ptr<ReportQueueConfiguration> config);
- // Instantiates ReportQueueProvider singleton based on the overall process
- // state and will refer to StorageModuleInterface and optional Uploader
- // accordingly.
- static ReportQueueProvider* GetInstance();
- static bool IsEncryptedReportingPipelineEnabled();
- // Accessors.
- base::WeakPtr<ReportQueueProvider> GetWeakPtr();
- scoped_refptr<StorageModuleInterface> storage() const;
- scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner() const;
- // Storage module creator (can be substituted for testing purposes).
- StorageModuleCreateCallback storage_create_cb_;
- private:
- // Holds the creation request for a ReportQueue.
- class CreateReportQueueRequest;
- // Finalizes provider, if the initialization process succeeded.
- // May to be overridden by subclass to make more updates to the provider.
- virtual void OnInitCompleted();
- // Creates and initializes queue implementation. Returns status in case of
- // error.
- virtual void CreateNewQueue(std::unique_ptr<ReportQueueConfiguration> config,
- CreateReportQueueCallback cb);
- virtual StatusOr<std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter>>
- CreateNewSpeculativeQueue();
- // Configures a given report queue config with appropriate DM tokens after its
- // retrieval so it can be used for downstream processing while building a
- // report queue, and triggers the corresponding completion callback with the
- // updated config.
- virtual void ConfigureReportQueue(
- std::unique_ptr<ReportQueueConfiguration> report_queue_config,
- ReportQueueConfiguredCallback completion_cb) = 0;
- // Checks whether the provider has been initialized, and if so, processes all
- // pending queue creation requests.
- void CheckInitializationState();
- // Processes storage or error returned by async call to `storage_create_cb_`.
- void OnStorageModuleConfigured(
- StatusOr<scoped_refptr<StorageModuleInterface>> storage_result);
- // Task runner used for guarding the provider elements.
- scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
- SEQUENCE_CHECKER(sequence_checker_);
- // Queue for storing creation requests while the provider is
- // initializing.
- std::queue<std::unique_ptr<CreateReportQueueRequest>> create_request_queue_
- GUARDED_BY_CONTEXT(sequence_checker_);
- // Storage module associated with the provider. It serves all queues created
- // by it. `storage_` is null initially and when it becomes non-null, the
- // provider is ready to create actual queues (speculative queues can be
- // created before that as well).
- scoped_refptr<StorageModuleInterface> storage_
- GUARDED_BY_CONTEXT(sequence_checker_);
- // Weak pointer factory.
- base::WeakPtrFactory<ReportQueueProvider> weak_ptr_factory_{this};
- };
- } // namespace reporting
- #endif // COMPONENTS_REPORTING_CLIENT_REPORT_QUEUE_PROVIDER_H_
|