1 // Copyright 2020 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 #ifndef CHROME_BROWSER_POLICY_MESSAGING_LAYER_PUBLIC_REPORT_QUEUE_H_
6 #define CHROME_BROWSER_POLICY_MESSAGING_LAYER_PUBLIC_REPORT_QUEUE_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "base/callback.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_refptr.h"
15 #include "base/sequence_checker.h"
16 #include "base/sequenced_task_runner.h"
17 #include "base/values.h"
18 #include "chrome/browser/policy/messaging_layer/public/report_queue_configuration.h"
19 #include "chrome/browser/policy/messaging_layer/storage/storage_module.h"
20 #include "chrome/browser/policy/messaging_layer/util/status.h"
21 #include "chrome/browser/policy/messaging_layer/util/statusor.h"
22 #include "components/policy/proto/record.pb.h"
23 #include "components/policy/proto/record_constants.pb.h"
24 #include "third_party/protobuf/src/google/protobuf/message_lite.h"
25 
26 namespace reporting {
27 
28 // A |ReportQueue| is configured with a |ReportQueueConfiguration|.  A
29 // |ReportQueue| allows a user to |Enqueue| a message for delivery to a handler
30 // specified by the |Destination| held by the provided
31 // |ReportQueueConfiguration|. |ReportQueue| handles scheduling storage and
32 // delivery.
33 //
34 // ReportQueues are not meant to be created directly, instead use the
35 // reporting::ReportingClient::CreateReportQueue(...) function. See the comments
36 // for reporting::ReportingClient for example usage.
37 //
38 // Enqueue can also be used with a |base::Value| or |std::string|.
39 class ReportQueue {
40  public:
41   // An EnqueueCallbacks are called on the completion of any |Enqueue| call.
42   using EnqueueCallback = base::OnceCallback<void(Status)>;
43 
44   // Factory
45   static std::unique_ptr<ReportQueue> Create(
46       std::unique_ptr<ReportQueueConfiguration> config,
47       scoped_refptr<StorageModule> storage);
48 
49   virtual ~ReportQueue();
50   ReportQueue(const ReportQueue& other) = delete;
51   ReportQueue& operator=(const ReportQueue& other) = delete;
52 
53   // Enqueue asynchronously stores and delivers a record.  The |callback| will
54   // be called on any errors. If storage is successful |callback| will be called
55   // with an OK status.
56   //
57   // |priority| will Enqueue the record to the specified Priority queue.
58   //
59   // The current destinations have the following data requirements:
60   // (destination : requirement)
61   // UPLOAD_EVENTS : UploadEventsRequest
62   //
63   // |record| will be sent as a string with no conversion.
64   virtual void Enqueue(base::StringPiece record,
65                        Priority priority,
66                        EnqueueCallback callback) const;
67 
68   // |record| will be converted to a JSON string with base::JsonWriter::Write.
69   virtual void Enqueue(const base::Value& record,
70                        Priority priority,
71                        EnqueueCallback callback) const;
72 
73   // |record| will be converted to a string with SerializeToString(). The
74   // handler is responsible for converting the record back to a proto with a
75   // ParseFromString() call.
76   virtual void Enqueue(google::protobuf::MessageLite* record,
77                        Priority priority,
78                        EnqueueCallback callback) const;
79 
80  protected:
81   ReportQueue(std::unique_ptr<ReportQueueConfiguration> config,
82               scoped_refptr<StorageModule> storage);
83 
84  private:
85   void AddRecord(base::StringPiece record,
86                  Priority priority,
87                  EnqueueCallback callback) const;
88 
89   void SendRecordToStorage(base::StringPiece record,
90                            Priority priority,
91                            EnqueueCallback callback) const;
92 
93   StatusOr<std::string> ValueToJson(const base::Value& record) const;
94   StatusOr<std::string> ProtoToString(
95       google::protobuf::MessageLite* record) const;
96 
97   reporting::Record AugmentRecord(base::StringPiece record_data) const;
98 
99   std::unique_ptr<ReportQueueConfiguration> config_;
100   scoped_refptr<StorageModule> storage_;
101   SEQUENCE_CHECKER(sequence_checker_);
102 
103   scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
104 };
105 
106 }  // namespace reporting
107 
108 #endif  // CHROME_BROWSER_POLICY_MESSAGING_LAYER_PUBLIC_REPORT_QUEUE_H_
109