File: encrypted_reporting_client.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (215 lines) | stat: -rw-r--r-- 8,941 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_ENCRYPTED_REPORTING_CLIENT_H_
#define CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_ENCRYPTED_REPORTING_CLIENT_H_

#include <list>
#include <memory>
#include <optional>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "chrome/browser/policy/messaging_layer/util/upload_declarations.h"
#include "chrome/browser/policy/messaging_layer/util/upload_response_parser.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/device_management_service.h"
#include "components/policy/core/common/cloud/encrypted_reporting_job_configuration.h"
#include "components/reporting/proto/synced/record.pb.h"
#include "components/reporting/proto/synced/record_constants.pb.h"
#include "components/reporting/resources/resource_manager.h"
#include "components/reporting/util/statusor.h"

namespace reporting {

// Implements the logic required to talk to the device management service
// for Encrypted Reporting Pipeline records upload.
class EncryptedReportingClient {
 public:
  class Delegate {
   public:
    Delegate() = default;

    Delegate(const Delegate&) = delete;
    Delegate& operator=(const Delegate&) = delete;

    virtual ~Delegate() = default;

    virtual policy::DeviceManagementService* device_management_service() const;
  };

  // Reports accumulated payload sizes per hour via UMA.
  class PayloadSizePerHourUmaReporter {
   public:
    PayloadSizePerHourUmaReporter();
    ~PayloadSizePerHourUmaReporter();
    PayloadSizePerHourUmaReporter(const PayloadSizePerHourUmaReporter&) =
        delete;
    PayloadSizePerHourUmaReporter& operator=(
        const PayloadSizePerHourUmaReporter&) = delete;

    // Adds request payload size to the accumulated request payload size.
    void RecordRequestPayloadSize(int payload_size);

    // Adds response payload size to the accumulated response payload size.
    void RecordResponsePayloadSize(int payload_size);

    // Gets the weak pointer.
    base::WeakPtr<PayloadSizePerHourUmaReporter> GetWeakPtr();

   private:
    // Reporting interval.
    static constexpr base::TimeDelta kReportingInterval = base::Hours(1);

    // Converts bytes to KiB.
    static int ConvertBytesToKiB(int bytes);

    // Reports the data to UMA.
    void Report();

    // Accumulated request payload size since last report.
    int request_payload_size_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;

    // Accumulated response payload size since last report.
    int response_payload_size_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;

    // Timer that controls when network usage is reported.
    base::RepeatingTimer timer_;

    SEQUENCE_CHECKER(sequence_checker_);

    base::WeakPtrFactory<PayloadSizePerHourUmaReporter> weak_factory_{this};
  };

  using ResponseCallback =
      base::OnceCallback<void(StatusOr<UploadResponseParser>)>;

  // Server is expected to respond within this time, otherwise the upload
  // job is cancelled and the data will be re-uploaded as soon as the throttling
  // permits.
  static constexpr base::TimeDelta kReportingUploadDeadline = base::Minutes(2);

  static std::unique_ptr<EncryptedReportingClient> Create(
      std::unique_ptr<Delegate> delegate = std::make_unique<Delegate>());

  EncryptedReportingClient(const EncryptedReportingClient&) = delete;
  EncryptedReportingClient& operator=(const EncryptedReportingClient&) = delete;

  ~EncryptedReportingClient();

  // Returns true if a generation guid is required for this device or browser.
  // Returns false otherwise.
  static bool GenerationGuidIsRequired();

  // Presets common settings to be applied to future cached uploads. May be
  // called more than once, but settings are expected to end up being the same.
  void PresetUploads(base::Value::Dict context,
                     std::string dm_token,
                     std::string client_id);

  // Uploads a report containing multiple `records`, augmented with
  // `need_encryption_key` flag and `config_file_version`. Calls `callback` when
  // the upload process is completed. Uses `scoped_reservation` to ensure proper
  // memory management (stops and returns error if memory is insufficient).
  void UploadReport(bool need_encryption_key,
                    int config_file_version,
                    std::vector<EncryptedRecord> records,
                    ScopedReservation scoped_reservation,
                    UploadEnqueuedCallback enqueued_cb,
                    ResponseCallback callback);

  // Test-only method that resets collected uploads state.
  static void ResetUploadsStateForTest();

 private:
  friend class EncryptedReportingClientTest;
  FRIEND_TEST_ALL_PREFIXES(EncryptedReportingClientTest,
                           IdenticalUploadRetriesThrottled);
  FRIEND_TEST_ALL_PREFIXES(EncryptedReportingClientTest,
                           UploadsSequenceThrottled);
  FRIEND_TEST_ALL_PREFIXES(EncryptedReportingClientTest,
                           SecurityUploadsSequenceNotThrottled);
  FRIEND_TEST_ALL_PREFIXES(EncryptedReportingClientTest,
                           FailedUploadsSequenceThrottled);

  // Constructor called by factory only.
  explicit EncryptedReportingClient(std::unique_ptr<Delegate> delegate);

  // Performs actual upload unless one is already in flight (calls `callback`
  // with error in that case).
  void MaybePerformUpload(bool need_encryption_key,
                          int config_file_version,
                          Priority priority,
                          int64_t generation_id,
                          ResponseCallback callback);

  // Constructs upload job after the data is converted into JSON, assigned to
  // `payload_result` (`nullopt` if there was an error). Calls `callback` once
  // the job has been responded or if an error has been detected, and releases
  // `scoped_reservation`.
  void CreateUploadJob(
      Priority priority,
      int64_t generation_id,
      policy::EncryptedReportingJobConfiguration::UploadResponseCallback
          response_cb,
      ResponseCallback callback,
      std::optional<base::Value::Dict> payload_result,
      ScopedReservation scoped_reservation,
      int64_t last_sequence_id,
      uint64_t events_to_send);

  // Callback for encrypted report upload requests.
  void OnReportUploadCompleted(Priority priority,
                               int64_t generation_id,
                               ScopedReservation scoped_reservation,
                               std::optional<int> request_payload_size,
                               base::WeakPtr<PayloadSizePerHourUmaReporter>
                                   payload_size_per_hour_uma_reporter,
                               ResponseCallback callback,
                               policy::DeviceManagementService::Job* job,
                               policy::DeviceManagementStatus status,
                               int response_code,
                               std::optional<base::Value::Dict> response);

  // Checks the new job against the history, determines how soon the upload will
  // be allowed. Returns positive value if not allowed, and 0 or negative
  // otherwise.
  static base::TimeDelta WhenIsAllowedToProceed(Priority priority,
                                                int64_t generation_id);

  // Account for the job, that was allowed to proceed.
  static void AccountForAllowedJob(Priority priority,
                                   int64_t generation_id,
                                   int64_t last_sequence_id);

  // Accounts for net error and response code of the upload.
  static void AccountForUploadResponse(Priority priority,
                                       int64_t generation_id,
                                       int net_error,
                                       int response_code);

  SEQUENCE_CHECKER(sequence_checker_);

  // Cached elements expected by the reporting server.
  std::string dm_token_ GUARDED_BY_CONTEXT(sequence_checker_);
  std::string client_id_ GUARDED_BY_CONTEXT(sequence_checker_);
  base::Value::Dict context_ GUARDED_BY_CONTEXT(sequence_checker_);

  const std::unique_ptr<Delegate> delegate_;

  // Reports accumulated payload sizes per hour via UMA.
  PayloadSizePerHourUmaReporter payload_size_per_hour_uma_reporter_;

  base::WeakPtrFactory<EncryptedReportingClient> weak_ptr_factory_{this};
};
}  // namespace reporting

#endif  // CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_ENCRYPTED_REPORTING_CLIENT_H_