• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.h"
6 
7 #include <list>
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "base/feature_list.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/functional/bind.h"
18 #include "base/functional/callback_helpers.h"
19 #include "base/json/json_reader.h"
20 #include "base/json/json_string_value_serializer.h"
21 #include "base/metrics/histogram_macros.h"
22 #include "base/task/sequenced_task_runner.h"
23 #include "base/task/task_traits.h"
24 #include "base/thread_annotations.h"
25 #include "net/base/features.h"
26 #include "net/base/network_anonymization_key.h"
27 #include "net/extras/sqlite/sqlite_persistent_store_backend_base.h"
28 #include "net/reporting/reporting_endpoint.h"
29 #include "sql/database.h"
30 #include "sql/meta_table.h"
31 #include "sql/statement.h"
32 #include "sql/transaction.h"
33 #include "url/origin.h"
34 
35 namespace net {
36 
37 namespace {
38 // Version 1 - 2019/03 - crrev.com/c/1504493, crrev.com/c/1560456
39 //
40 // Version 1 adds tables for NEL policies, Reporting endpoints, and Reporting
41 // endpoint groups.
42 //
43 // Version 2 - 2020/10 - https://crrev.com/c/2485253
44 //
45 // Version 2 adds NetworkAnonymizationKey fields to all entries. When migrating,
46 // existing entries get an empty NetworkAnonymizationKey value.
47 const int kCurrentVersionNumber = 2;
48 const int kCompatibleVersionNumber = 2;
49 
50 // Histogram names
51 const char kNumberOfLoadedNelPoliciesHistogramName[] =
52     "ReportingAndNEL.NumberOfLoadedNELPolicies";
53 const char kNumberOfLoadedNelPolicies2HistogramName[] =
54     "ReportingAndNEL.NumberOfLoadedNELPolicies2";
55 const char kNumberOfLoadedReportingEndpoints2HistogramName[] =
56     "ReportingAndNEL.NumberOfLoadedReportingEndpoints2";
57 const char kNumberOfLoadedReportingEndpointGroups2HistogramName[] =
58     "ReportingAndNEL.NumberOfLoadedReportingEndpointGroups2";
59 }  // namespace
60 
GetReportingAndNelStoreBackgroundSequencePriority()61 base::TaskPriority GetReportingAndNelStoreBackgroundSequencePriority() {
62   return base::TaskPriority::USER_BLOCKING;
63 }
64 
65 // Converts a NetworkAnonymizationKey to a string for serializing to disk.
66 // Returns false on failure, which happens for transient keys that should not be
67 // serialized to disk.
NetworkAnonymizationKeyToString(const NetworkAnonymizationKey & network_anonymization_key,std::string * out_string)68 [[nodiscard]] bool NetworkAnonymizationKeyToString(
69     const NetworkAnonymizationKey& network_anonymization_key,
70     std::string* out_string) {
71   base::Value value;
72   if (!network_anonymization_key.ToValue(&value))
73     return false;
74   return JSONStringValueSerializer(out_string).Serialize(value);
75 }
76 
77 // Attempts to convert a string returned by NetworkAnonymizationKeyToString() to
78 // a NetworkAnonymizationKey. Returns false on failure.
NetworkAnonymizationKeyFromString(const std::string & string,NetworkAnonymizationKey * out_network_anonymization_key)79 [[nodiscard]] bool NetworkAnonymizationKeyFromString(
80     const std::string& string,
81     NetworkAnonymizationKey* out_network_anonymization_key) {
82   absl::optional<base::Value> value = base::JSONReader::Read(string);
83   if (!value)
84     return false;
85 
86   if (!NetworkAnonymizationKey::FromValue(*value,
87                                           out_network_anonymization_key))
88     return false;
89 
90   // If network state partitionining is disabled, but the
91   // NetworkAnonymizationKeys is non-empty, ignore the entry. The entry will
92   // still be in the on-disk database, in case NAKs are re-enabled, it just
93   // won't be loaded into memory. The entry could still be loaded with an empty
94   // NetworkAnonymizationKey, but that would require logic to resolve conflicts.
95   if (!out_network_anonymization_key->IsEmpty() &&
96       !NetworkAnonymizationKey::IsPartitioningEnabled()) {
97     *out_network_anonymization_key = NetworkAnonymizationKey();
98     return false;
99   }
100 
101   return true;
102 }
103 
104 class SQLitePersistentReportingAndNelStore::Backend
105     : public SQLitePersistentStoreBackendBase {
106  public:
Backend(const base::FilePath & path,const scoped_refptr<base::SequencedTaskRunner> & client_task_runner,const scoped_refptr<base::SequencedTaskRunner> & background_task_runner)107   Backend(
108       const base::FilePath& path,
109       const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
110       const scoped_refptr<base::SequencedTaskRunner>& background_task_runner)
111       : SQLitePersistentStoreBackendBase(
112             path,
113             /* histogram_tag = */ "ReportingAndNEL",
114             kCurrentVersionNumber,
115             kCompatibleVersionNumber,
116             background_task_runner,
117             client_task_runner,
118             /*enable_exclusive_access=*/false) {}
119 
120   Backend(const Backend&) = delete;
121   Backend& operator=(const Backend&) = delete;
122 
123   void LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback);
124   void AddNelPolicy(const NetworkErrorLoggingService::NelPolicy& policy);
125   void UpdateNelPolicyAccessTime(
126       const NetworkErrorLoggingService::NelPolicy& policy);
127   void DeleteNelPolicy(const NetworkErrorLoggingService::NelPolicy& policy);
128 
129   void LoadReportingClients(ReportingClientsLoadedCallback loaded_callback);
130   void AddReportingEndpoint(const ReportingEndpoint& endpoint);
131   void AddReportingEndpointGroup(const CachedReportingEndpointGroup& group);
132   void UpdateReportingEndpointGroupAccessTime(
133       const CachedReportingEndpointGroup& group);
134   void UpdateReportingEndpointDetails(const ReportingEndpoint& endpoint);
135   void UpdateReportingEndpointGroupDetails(
136       const CachedReportingEndpointGroup& group);
137   void DeleteReportingEndpoint(const ReportingEndpoint& endpoint);
138   void DeleteReportingEndpointGroup(const CachedReportingEndpointGroup& group);
139 
140   // Gets the number of queued operations.
141   size_t GetQueueLengthForTesting() const;
142 
143  private:
~Backend()144   ~Backend() override {
145     DCHECK(nel_policy_pending_ops_.empty());
146     DCHECK(reporting_endpoint_pending_ops_.empty());
147     DCHECK(reporting_endpoint_group_pending_ops_.empty());
148     DCHECK_EQ(0u, num_pending_);
149   }
150 
151   // Represents a mutating operation to the database, specified by a type (add,
152   // update access time, update data, or delete) and data representing the entry
153   // in the database to be added/updated/deleted.
154   template <typename DataType>
155   class PendingOperation;
156 
157   // Types of PendingOperation. Here to avoid templatizing the enum.
158   enum class PendingOperationType {
159     ADD,
160     UPDATE_ACCESS_TIME,
161     UPDATE_DETAILS,
162     DELETE
163   };
164 
165   // List of pending operations for a particular entry in the database.
166   template <typename DataType>
167   using PendingOperationsVector =
168       std::vector<std::unique_ptr<PendingOperation<DataType>>>;
169 
170   // A copy of the information relevant to a NEL policy.
171   struct NelPolicyInfo;
172   // A copy of the information relevant to a Reporting endpoint.
173   struct ReportingEndpointInfo;
174   // A copy of the information relevant to a Reporting endpoint group.
175   struct ReportingEndpointGroupInfo;
176   // TODO(chlily): add ReportingReportInfo.
177 
178   // Uniquely identifies an endpoint in the store.
179   using ReportingEndpointKey = std::pair<ReportingEndpointGroupKey, GURL>;
180 
181   // Map of pending operations for each entry in the database.
182   // Key types are: - url::Origin for NEL policies,
183   //                - ReportingEndpointKey for Reporting endpoints,
184   //                - ReportingEndpointGroupKey for Reporting endpoint groups
185   //                  (defined in //net/reporting/reporting_endpoint.h).
186   template <typename KeyType, typename DataType>
187   using QueueType = std::map<KeyType, PendingOperationsVector<DataType>>;
188 
189   // SQLitePersistentStoreBackendBase implementation
190   bool CreateDatabaseSchema() override;
191   absl::optional<int> DoMigrateDatabaseSchema() override;
192   void DoCommit() override;
193 
194   // Commit a pending operation pertaining to a NEL policy.
195   // Returns true on success.
196   bool CommitNelPolicyOperation(PendingOperation<NelPolicyInfo>* op);
197   // Commit a pending operation pertaining to a Reporting endpoint.
198   // Returns true on success.
199   bool CommitReportingEndpointOperation(
200       PendingOperation<ReportingEndpointInfo>* op);
201   // Commit a pending operation pertaining to a Reporting endpoint group.
202   // Returns true on success.
203   bool CommitReportingEndpointGroupOperation(
204       PendingOperation<ReportingEndpointGroupInfo>* op);
205 
206   // Add a pending operation to the appropriate queue.
207   template <typename KeyType, typename DataType>
208   void BatchOperation(KeyType key,
209                       std::unique_ptr<PendingOperation<DataType>> po,
210                       QueueType<KeyType, DataType>* queue);
211 
212   // If there are existing pending operations for a given key, potentially
213   // remove some of the existing operations before adding |new_op|.
214   // In particular, if |new_op| is a deletion, then all the previous pending
215   // operations are made irrelevant and can be deleted. If |new_op| is an
216   // update-access-time, and the last operation in |ops_for_key| is also an
217   // update-access-time, then it can be discarded because |new_op| is about to
218   // overwrite the access time with a new value anyway. Similarly for
219   // update-details.
220   template <typename DataType>
221   void MaybeCoalesceOperations(PendingOperationsVector<DataType>* ops_for_key,
222                                PendingOperation<DataType>* new_op)
223       EXCLUSIVE_LOCKS_REQUIRED(lock_);
224 
225   // After adding a pending operation to one of the pending operations queues,
226   // this method posts a task to commit all pending operations if we reached the
227   // batch size, or starts a timer to commit after a time interval if we just
228   // started a new batch. |num_pending| is the total number of pending
229   // operations after the one we just added.
230   void OnOperationBatched(size_t num_pending);
231 
232   // Loads NEL policies into a vector in the background, then posts a
233   // task to the client task runner to call |loaded_callback| with the loaded
234   // NEL policies.
235   void LoadNelPoliciesAndNotifyInBackground(
236       NelPoliciesLoadedCallback loaded_callback);
237 
238   // Calls |loaded_callback| with the loaded NEL policies (which may be empty if
239   // loading was unsuccessful). If loading was successful, also report metrics.
240   void CompleteLoadNelPoliciesAndNotifyInForeground(
241       NelPoliciesLoadedCallback loaded_callback,
242       std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies,
243       bool load_success);
244 
245   // Loads Reporting endpoints and endpoint groups into two vectors in the
246   // background, then posts a task to the client task runner to call
247   // |loaded_callback| with the loaded endpoints and endpoint groups.
248   void LoadReportingClientsAndNotifyInBackground(
249       ReportingClientsLoadedCallback loaded_callback);
250 
251   // Calls |loaded_callback| with the loaded endpoints and endpoint groups
252   // (which may be empty if loading was unsuccessful). If loading was
253   // successful, also report metrics.
254   void CompleteLoadReportingClientsAndNotifyInForeground(
255       ReportingClientsLoadedCallback loaded_callback,
256       std::vector<ReportingEndpoint> loaded_endpoints,
257       std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups,
258       bool load_success);
259 
260   void RecordNumberOfLoadedNelPolicies(size_t count);
261   void RecordNumberOfLoadedReportingEndpoints(size_t count);
262   void RecordNumberOfLoadedReportingEndpointGroups(size_t count);
263 
264   // Total number of pending operations (may not match the sum of the number of
265   // elements in the pending operations queues, due to operation coalescing).
266   size_t num_pending_ GUARDED_BY(lock_) = 0;
267 
268   // Queue of pending operations pertaining to NEL policies, keyed on origin.
269   QueueType<NetworkErrorLoggingService::NelPolicyKey, NelPolicyInfo>
270       nel_policy_pending_ops_ GUARDED_BY(lock_);
271   // Queue of pending operations pertaining to Reporting endpoints, keyed on
272   // origin, group name, and url.
273   QueueType<ReportingEndpointKey, ReportingEndpointInfo>
274       reporting_endpoint_pending_ops_ GUARDED_BY(lock_);
275   // Queue of pending operations pertaining to Reporting endpoint groups, keyed
276   // on origin and group name.
277   QueueType<ReportingEndpointGroupKey, ReportingEndpointGroupInfo>
278       reporting_endpoint_group_pending_ops_ GUARDED_BY(lock_);
279 
280   // TODO(chlily): add reporting_report_pending_ops_ for Reporting reports.
281 
282   // Protects |num_pending_|, and all the pending operations queues.
283   mutable base::Lock lock_;
284 };
285 
286 namespace {
287 
CreateV2NelPoliciesSchema(sql::Database * db)288 bool CreateV2NelPoliciesSchema(sql::Database* db) {
289   DCHECK(!db->DoesTableExist("nel_policies"));
290 
291   std::string stmt =
292       "CREATE TABLE nel_policies ("
293       "  nik TEXT NOT NULL,"
294       "  origin_scheme TEXT NOT NULL,"
295       "  origin_host TEXT NOT NULL,"
296       "  origin_port INTEGER NOT NULL,"
297       "  received_ip_address TEXT NOT NULL,"
298       "  group_name TEXT NOT NULL,"
299       "  expires_us_since_epoch INTEGER NOT NULL,"
300       "  success_fraction REAL NOT NULL,"
301       "  failure_fraction REAL NOT NULL,"
302       "  is_include_subdomains INTEGER NOT NULL,"
303       "  last_access_us_since_epoch INTEGER NOT NULL,"
304       // Each (origin, nik) specifies at most one NEL policy.
305       "  UNIQUE (origin_scheme, origin_host, origin_port, nik)"
306       ")";
307 
308   return db->Execute(stmt.c_str());
309 }
310 
CreateV2ReportingEndpointsSchema(sql::Database * db)311 bool CreateV2ReportingEndpointsSchema(sql::Database* db) {
312   DCHECK(!db->DoesTableExist("reporting_endpoints"));
313 
314   std::string stmt =
315       "CREATE TABLE reporting_endpoints ("
316       "  nik TEXT NOT NULL,"
317       "  origin_scheme TEXT NOT NULL,"
318       "  origin_host TEXT NOT NULL,"
319       "  origin_port INTEGER NOT NULL,"
320       "  group_name TEXT NOT NULL,"
321       "  url TEXT NOT NULL,"
322       "  priority INTEGER NOT NULL,"
323       "  weight INTEGER NOT NULL,"
324       // Each (origin, group, url, nik) tuple specifies at most one endpoint.
325       "  UNIQUE (origin_scheme, origin_host, origin_port, group_name, url, nik)"
326       ")";
327 
328   return db->Execute(stmt.c_str());
329 }
330 
CreateV2ReportingEndpointGroupsSchema(sql::Database * db)331 bool CreateV2ReportingEndpointGroupsSchema(sql::Database* db) {
332   DCHECK(!db->DoesTableExist("reporting_endpoint_groups"));
333 
334   std::string stmt =
335       "CREATE TABLE reporting_endpoint_groups ("
336       "  nik TEXT NOT NULL,"
337       "  origin_scheme TEXT NOT NULL,"
338       "  origin_host TEXT NOT NULL,"
339       "  origin_port INTEGER NOT NULL,"
340       "  group_name TEXT NOT NULL,"
341       "  is_include_subdomains INTEGER NOT NULL,"
342       "  expires_us_since_epoch INTEGER NOT NULL,"
343       "  last_access_us_since_epoch INTEGER NOT NULL,"
344       // Each (origin, group, nik) tuple specifies at most one endpoint group.
345       "  UNIQUE (origin_scheme, origin_host, origin_port, group_name, nik)"
346       ")";
347 
348   return db->Execute(stmt.c_str());
349 }
350 
351 }  // namespace
352 
353 template <typename DataType>
354 class SQLitePersistentReportingAndNelStore::Backend::PendingOperation {
355  public:
PendingOperation(PendingOperationType type,DataType data)356   PendingOperation(PendingOperationType type, DataType data)
357       : type_(type), data_(std::move(data)) {}
358 
type() const359   PendingOperationType type() const { return type_; }
data() const360   const DataType& data() const { return data_; }
361 
362  private:
363   const PendingOperationType type_;
364   const DataType data_;
365 };
366 
367 // Makes a copy of the relevant information about a NelPolicy, stored in a
368 // form suitable for adding to the database.
369 // TODO(chlily): Add NIK.
370 struct SQLitePersistentReportingAndNelStore::Backend::NelPolicyInfo {
371   // This should only be invoked through CreatePendingOperation().
NelPolicyInfonet::SQLitePersistentReportingAndNelStore::Backend::NelPolicyInfo372   NelPolicyInfo(const NetworkErrorLoggingService::NelPolicy& nel_policy,
373                 std::string network_anonymization_key_string)
374       : network_anonymization_key_string(
375             std::move(network_anonymization_key_string)),
376         origin_scheme(nel_policy.key.origin.scheme()),
377         origin_host(nel_policy.key.origin.host()),
378         origin_port(nel_policy.key.origin.port()),
379         received_ip_address(nel_policy.received_ip_address.ToString()),
380         report_to(nel_policy.report_to),
381         expires_us_since_epoch(
382             nel_policy.expires.ToDeltaSinceWindowsEpoch().InMicroseconds()),
383         success_fraction(nel_policy.success_fraction),
384         failure_fraction(nel_policy.failure_fraction),
385         is_include_subdomains(nel_policy.include_subdomains),
386         last_access_us_since_epoch(
387             nel_policy.last_used.ToDeltaSinceWindowsEpoch().InMicroseconds()) {}
388 
389   // Creates the specified operation for the given policy. Returns nullptr for
390   // endpoints with transient NetworkAnonymizationKeys.
391   static std::unique_ptr<PendingOperation<NelPolicyInfo>>
CreatePendingOperationnet::SQLitePersistentReportingAndNelStore::Backend::NelPolicyInfo392   CreatePendingOperation(
393       PendingOperationType type,
394       const NetworkErrorLoggingService::NelPolicy& nel_policy) {
395     std::string network_anonymization_key_string;
396     if (!NetworkAnonymizationKeyToString(
397             nel_policy.key.network_anonymization_key,
398             &network_anonymization_key_string)) {
399       return nullptr;
400     }
401 
402     return std::make_unique<PendingOperation<NelPolicyInfo>>(
403         type,
404         NelPolicyInfo(nel_policy, std::move(network_anonymization_key_string)));
405   }
406 
407   // NetworkAnonymizationKey associated with the request that received the
408   // policy, converted to a string via NetworkAnonymizationKeyToString().
409   std::string network_anonymization_key_string;
410 
411   // Origin the policy was received from.
412   std::string origin_scheme;
413   std::string origin_host;
414   int origin_port = 0;
415 
416   // IP address of the server that the policy was received from.
417   std::string received_ip_address;
418   // The Reporting group which the policy specifies.
419   std::string report_to;
420   // When the policy expires, in microseconds since the Windows epoch.
421   int64_t expires_us_since_epoch = 0;
422   // Sampling fractions.
423   double success_fraction = 0.0;
424   double failure_fraction = 1.0;
425   // Whether the policy applies to subdomains of the origin.
426   bool is_include_subdomains = false;
427   // Last time the policy was updated or used, in microseconds since the
428   // Windows epoch.
429   int64_t last_access_us_since_epoch = 0;
430 };
431 
432 // Makes a copy of the relevant information about a ReportingEndpoint, stored in
433 // a form suitable for adding to the database.
434 struct SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointInfo {
435   // This should only be invoked through CreatePendingOperation().
ReportingEndpointInfonet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointInfo436   ReportingEndpointInfo(const ReportingEndpoint& endpoint,
437                         std::string network_anonymization_key_string)
438       : network_anonymization_key_string(
439             std::move(network_anonymization_key_string)),
440         origin_scheme(endpoint.group_key.origin.scheme()),
441         origin_host(endpoint.group_key.origin.host()),
442         origin_port(endpoint.group_key.origin.port()),
443         group_name(endpoint.group_key.group_name),
444         url(endpoint.info.url.spec()),
445         priority(endpoint.info.priority),
446         weight(endpoint.info.weight) {}
447 
448   // Creates the specified operation for the given endpoint. Returns nullptr for
449   // endpoints with transient NetworkAnonymizationKeys.
450   static std::unique_ptr<PendingOperation<ReportingEndpointInfo>>
CreatePendingOperationnet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointInfo451   CreatePendingOperation(PendingOperationType type,
452                          const ReportingEndpoint& endpoint) {
453     std::string network_anonymization_key_string;
454     if (!NetworkAnonymizationKeyToString(
455             endpoint.group_key.network_anonymization_key,
456             &network_anonymization_key_string)) {
457       return nullptr;
458     }
459 
460     return std::make_unique<PendingOperation<ReportingEndpointInfo>>(
461         type, ReportingEndpointInfo(
462                   endpoint, std::move(network_anonymization_key_string)));
463   }
464 
465   // NetworkAnonymizationKey associated with the endpoint, converted to a string
466   // via NetworkAnonymizationKeyString().
467   std::string network_anonymization_key_string;
468 
469   // Origin the endpoint was received from.
470   std::string origin_scheme;
471   std::string origin_host;
472   int origin_port = 0;
473 
474   // Name of the group the endpoint belongs to.
475   std::string group_name;
476   // URL of the endpoint.
477   std::string url;
478   // Priority of the endpoint.
479   int priority = ReportingEndpoint::EndpointInfo::kDefaultPriority;
480   // Weight of the endpoint.
481   int weight = ReportingEndpoint::EndpointInfo::kDefaultWeight;
482 };
483 
484 struct SQLitePersistentReportingAndNelStore::Backend::
485     ReportingEndpointGroupInfo {
ReportingEndpointGroupInfonet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointGroupInfo486   ReportingEndpointGroupInfo(const CachedReportingEndpointGroup& group,
487                              std::string network_anonymization_key_string)
488       : network_anonymization_key_string(
489             std::move(network_anonymization_key_string)),
490         origin_scheme(group.group_key.origin.scheme()),
491         origin_host(group.group_key.origin.host()),
492         origin_port(group.group_key.origin.port()),
493         group_name(group.group_key.group_name),
494         is_include_subdomains(group.include_subdomains ==
495                               OriginSubdomains::INCLUDE),
496         expires_us_since_epoch(
497             group.expires.ToDeltaSinceWindowsEpoch().InMicroseconds()),
498         last_access_us_since_epoch(
499             group.last_used.ToDeltaSinceWindowsEpoch().InMicroseconds()) {}
500 
501   // Creates the specified operation for the given endpoint reporting group.
502   // Returns nullptr for groups with transient NetworkAnonymizationKeys.
503   static std::unique_ptr<PendingOperation<ReportingEndpointGroupInfo>>
CreatePendingOperationnet::SQLitePersistentReportingAndNelStore::Backend::ReportingEndpointGroupInfo504   CreatePendingOperation(PendingOperationType type,
505                          const CachedReportingEndpointGroup& group) {
506     std::string network_anonymization_key_string;
507     if (!NetworkAnonymizationKeyToString(
508             group.group_key.network_anonymization_key,
509             &network_anonymization_key_string)) {
510       return nullptr;
511     }
512 
513     return std::make_unique<PendingOperation<ReportingEndpointGroupInfo>>(
514         type, ReportingEndpointGroupInfo(
515                   group, std::move(network_anonymization_key_string)));
516   }
517 
518   // NetworkAnonymizationKey associated with the endpoint group, converted to a
519   // string via NetworkAnonymizationKeyToString().
520   std::string network_anonymization_key_string;
521 
522   // Origin the endpoint group was received from.
523   std::string origin_scheme;
524   std::string origin_host;
525   int origin_port = 0;
526 
527   // Name of the group.
528   std::string group_name;
529   // Whether the group applies to subdomains of the origin.
530   bool is_include_subdomains = false;
531   // When the group expires, in microseconds since the Windows epoch.
532   int64_t expires_us_since_epoch = 0;
533   // Last time the group was updated or used, in microseconds since the Windows
534   // epoch.
535   int64_t last_access_us_since_epoch = 0;
536 };
537 
LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback)538 void SQLitePersistentReportingAndNelStore::Backend::LoadNelPolicies(
539     NelPoliciesLoadedCallback loaded_callback) {
540   PostBackgroundTask(
541       FROM_HERE, base::BindOnce(&Backend::LoadNelPoliciesAndNotifyInBackground,
542                                 this, std::move(loaded_callback)));
543 }
544 
AddNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)545 void SQLitePersistentReportingAndNelStore::Backend::AddNelPolicy(
546     const NetworkErrorLoggingService::NelPolicy& policy) {
547   auto po =
548       NelPolicyInfo::CreatePendingOperation(PendingOperationType::ADD, policy);
549   if (!po)
550     return;
551   BatchOperation(policy.key, std::move(po), &nel_policy_pending_ops_);
552 }
553 
UpdateNelPolicyAccessTime(const NetworkErrorLoggingService::NelPolicy & policy)554 void SQLitePersistentReportingAndNelStore::Backend::UpdateNelPolicyAccessTime(
555     const NetworkErrorLoggingService::NelPolicy& policy) {
556   auto po = NelPolicyInfo::CreatePendingOperation(
557       PendingOperationType::UPDATE_ACCESS_TIME, policy);
558   if (!po)
559     return;
560   BatchOperation(policy.key, std::move(po), &nel_policy_pending_ops_);
561 }
562 
DeleteNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)563 void SQLitePersistentReportingAndNelStore::Backend::DeleteNelPolicy(
564     const NetworkErrorLoggingService::NelPolicy& policy) {
565   auto po = NelPolicyInfo::CreatePendingOperation(PendingOperationType::DELETE,
566                                                   policy);
567   if (!po)
568     return;
569   BatchOperation(policy.key, std::move(po), &nel_policy_pending_ops_);
570 }
571 
LoadReportingClients(ReportingClientsLoadedCallback loaded_callback)572 void SQLitePersistentReportingAndNelStore::Backend::LoadReportingClients(
573     ReportingClientsLoadedCallback loaded_callback) {
574   PostBackgroundTask(
575       FROM_HERE,
576       base::BindOnce(&Backend::LoadReportingClientsAndNotifyInBackground, this,
577                      std::move(loaded_callback)));
578 }
579 
AddReportingEndpoint(const ReportingEndpoint & endpoint)580 void SQLitePersistentReportingAndNelStore::Backend::AddReportingEndpoint(
581     const ReportingEndpoint& endpoint) {
582   auto po = ReportingEndpointInfo::CreatePendingOperation(
583       PendingOperationType::ADD, endpoint);
584   if (!po)
585     return;
586   ReportingEndpointKey key =
587       std::make_pair(endpoint.group_key, endpoint.info.url);
588   BatchOperation(std::move(key), std::move(po),
589                  &reporting_endpoint_pending_ops_);
590 }
591 
AddReportingEndpointGroup(const CachedReportingEndpointGroup & group)592 void SQLitePersistentReportingAndNelStore::Backend::AddReportingEndpointGroup(
593     const CachedReportingEndpointGroup& group) {
594   auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
595       PendingOperationType::ADD, group);
596   if (!po)
597     return;
598   BatchOperation(group.group_key, std::move(po),
599                  &reporting_endpoint_group_pending_ops_);
600 }
601 
602 void SQLitePersistentReportingAndNelStore::Backend::
UpdateReportingEndpointGroupAccessTime(const CachedReportingEndpointGroup & group)603     UpdateReportingEndpointGroupAccessTime(
604         const CachedReportingEndpointGroup& group) {
605   auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
606       PendingOperationType::UPDATE_ACCESS_TIME, group);
607   if (!po)
608     return;
609   BatchOperation(group.group_key, std::move(po),
610                  &reporting_endpoint_group_pending_ops_);
611 }
612 
613 void SQLitePersistentReportingAndNelStore::Backend::
UpdateReportingEndpointDetails(const ReportingEndpoint & endpoint)614     UpdateReportingEndpointDetails(const ReportingEndpoint& endpoint) {
615   auto po = ReportingEndpointInfo::CreatePendingOperation(
616       PendingOperationType::UPDATE_DETAILS, endpoint);
617   if (!po)
618     return;
619   ReportingEndpointKey key =
620       std::make_pair(endpoint.group_key, endpoint.info.url);
621   BatchOperation(std::move(key), std::move(po),
622                  &reporting_endpoint_pending_ops_);
623 }
624 
625 void SQLitePersistentReportingAndNelStore::Backend::
UpdateReportingEndpointGroupDetails(const CachedReportingEndpointGroup & group)626     UpdateReportingEndpointGroupDetails(
627         const CachedReportingEndpointGroup& group) {
628   auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
629       PendingOperationType::UPDATE_DETAILS, group);
630   if (!po)
631     return;
632   BatchOperation(group.group_key, std::move(po),
633                  &reporting_endpoint_group_pending_ops_);
634 }
635 
DeleteReportingEndpoint(const ReportingEndpoint & endpoint)636 void SQLitePersistentReportingAndNelStore::Backend::DeleteReportingEndpoint(
637     const ReportingEndpoint& endpoint) {
638   auto po = ReportingEndpointInfo::CreatePendingOperation(
639       PendingOperationType::DELETE, endpoint);
640   if (!po)
641     return;
642   ReportingEndpointKey key =
643       std::make_pair(endpoint.group_key, endpoint.info.url);
644   BatchOperation(std::move(key), std::move(po),
645                  &reporting_endpoint_pending_ops_);
646 }
647 
648 void SQLitePersistentReportingAndNelStore::Backend::
DeleteReportingEndpointGroup(const CachedReportingEndpointGroup & group)649     DeleteReportingEndpointGroup(const CachedReportingEndpointGroup& group) {
650   auto po = ReportingEndpointGroupInfo::CreatePendingOperation(
651       PendingOperationType::DELETE, group);
652   if (!po)
653     return;
654   BatchOperation(group.group_key, std::move(po),
655                  &reporting_endpoint_group_pending_ops_);
656 }
657 
GetQueueLengthForTesting() const658 size_t SQLitePersistentReportingAndNelStore::Backend::GetQueueLengthForTesting()
659     const {
660   size_t count = 0;
661   {
662     base::AutoLock locked(lock_);
663     for (auto& key_and_pending_ops : nel_policy_pending_ops_) {
664       count += key_and_pending_ops.second.size();
665     }
666     for (auto& key_and_pending_ops : reporting_endpoint_pending_ops_) {
667       count += key_and_pending_ops.second.size();
668     }
669     for (auto& key_and_pending_ops : reporting_endpoint_group_pending_ops_) {
670       count += key_and_pending_ops.second.size();
671     }
672   }
673   return count;
674 }
675 
CreateDatabaseSchema()676 bool SQLitePersistentReportingAndNelStore::Backend::CreateDatabaseSchema() {
677   if (!db()->DoesTableExist("nel_policies") &&
678       !CreateV2NelPoliciesSchema(db())) {
679     return false;
680   }
681 
682   if (!db()->DoesTableExist("reporting_endpoints") &&
683       !CreateV2ReportingEndpointsSchema(db())) {
684     return false;
685   }
686 
687   if (!db()->DoesTableExist("reporting_endpoint_groups") &&
688       !CreateV2ReportingEndpointGroupsSchema(db())) {
689     return false;
690   }
691 
692   // TODO(chlily): Initialize tables for Reporting reports.
693 
694   return true;
695 }
696 
697 absl::optional<int>
DoMigrateDatabaseSchema()698 SQLitePersistentReportingAndNelStore::Backend::DoMigrateDatabaseSchema() {
699   int cur_version = meta_table()->GetVersionNumber();
700 
701   // Migrate from version 1 to version 2.
702   //
703   // For migration purposes, the NetworkAnonymizationKey field of the stored
704   // policies will be populated with an empty list, which corresponds to an
705   // empty NIK. This matches the behavior when NIKs are disabled. This will
706   // result in effectively clearing all policies once NIKs are enabled, at
707   // which point the the migration code should just be switched to deleting
708   // the old tables instead.
709   if (cur_version == 1) {
710     sql::Transaction transaction(db());
711     if (!transaction.Begin())
712       return absl::nullopt;
713 
714     // Migrate NEL policies table.
715     if (!db()->Execute("DROP TABLE IF EXISTS nel_policies_old; "
716                        "ALTER TABLE nel_policies RENAME TO nel_policies_old")) {
717       return absl::nullopt;
718     }
719     if (!CreateV2NelPoliciesSchema(db()))
720       return absl::nullopt;
721     // clang-format off
722     // The "report_to" field is renamed to "group_name" for consistency with
723     // the other tables.
724     std::string nel_policies_migrate_stmt =
725       "INSERT INTO nel_policies (nik, origin_scheme, origin_host, "
726       "  origin_port, group_name, received_ip_address, expires_us_since_epoch, "
727       "  success_fraction, failure_fraction, is_include_subdomains, "
728       "  last_access_us_since_epoch) "
729       "SELECT '[]', origin_scheme, origin_host, origin_port, "
730       "  report_to, received_ip_address, expires_us_since_epoch, "
731       "  success_fraction, failure_fraction, is_include_subdomains, "
732       "  last_access_us_since_epoch "
733       "FROM nel_policies_old" ;
734     // clang-format on
735     if (!db()->Execute(nel_policies_migrate_stmt.c_str()))
736       return absl::nullopt;
737     if (!db()->Execute("DROP TABLE nel_policies_old"))
738       return absl::nullopt;
739 
740     // Migrate Reporting endpoints table.
741     if (!db()->Execute("DROP TABLE IF EXISTS reporting_endpoints_old; "
742                        "ALTER TABLE reporting_endpoints RENAME TO "
743                        "reporting_endpoints_old")) {
744       return absl::nullopt;
745     }
746     if (!CreateV2ReportingEndpointsSchema(db()))
747       return absl::nullopt;
748     // clang-format off
749     std::string reporting_endpoints_migrate_stmt =
750       "INSERT INTO reporting_endpoints (nik,  origin_scheme, origin_host, "
751       "  origin_port, group_name, url, priority, weight) "
752       "SELECT '[]', origin_scheme, origin_host, origin_port, group_name, "
753       "  url, priority, weight "
754       "FROM reporting_endpoints_old" ;
755     // clang-format on
756     if (!db()->Execute(reporting_endpoints_migrate_stmt.c_str()))
757       return absl::nullopt;
758     if (!db()->Execute("DROP TABLE reporting_endpoints_old"))
759       return absl::nullopt;
760 
761     // Migrate Reporting endpoint groups table.
762     if (!db()->Execute("DROP TABLE IF EXISTS reporting_endpoint_groups_old; "
763                        "ALTER TABLE reporting_endpoint_groups RENAME TO "
764                        "reporting_endpoint_groups_old")) {
765       return absl::nullopt;
766     }
767     if (!CreateV2ReportingEndpointGroupsSchema(db()))
768       return absl::nullopt;
769     // clang-format off
770     std::string reporting_endpoint_groups_migrate_stmt =
771       "INSERT INTO reporting_endpoint_groups (nik,  origin_scheme, "
772       "  origin_host, origin_port, group_name, is_include_subdomains, "
773       "  expires_us_since_epoch, last_access_us_since_epoch) "
774       "SELECT '[]', origin_scheme, origin_host, origin_port, "
775       "  group_name, is_include_subdomains, expires_us_since_epoch, "
776       "  last_access_us_since_epoch "
777       "FROM reporting_endpoint_groups_old" ;
778     // clang-format on
779     if (!db()->Execute(reporting_endpoint_groups_migrate_stmt.c_str()))
780       return absl::nullopt;
781     if (!db()->Execute("DROP TABLE reporting_endpoint_groups_old"))
782       return absl::nullopt;
783 
784     ++cur_version;
785     if (!meta_table()->SetVersionNumber(cur_version) ||
786         !meta_table()->SetCompatibleVersionNumber(
787             std::min(cur_version, kCompatibleVersionNumber)) ||
788         !transaction.Commit()) {
789       return absl::nullopt;
790     }
791   }
792 
793   // Future database upgrade statements go here.
794 
795   return absl::make_optional(cur_version);
796 }
797 
DoCommit()798 void SQLitePersistentReportingAndNelStore::Backend::DoCommit() {
799   QueueType<NetworkErrorLoggingService::NelPolicyKey, NelPolicyInfo>
800       nel_policy_ops;
801   QueueType<ReportingEndpointKey, ReportingEndpointInfo> reporting_endpoint_ops;
802   QueueType<ReportingEndpointGroupKey, ReportingEndpointGroupInfo>
803       reporting_endpoint_group_ops;
804   size_t op_count = 0;
805   {
806     base::AutoLock locked(lock_);
807     nel_policy_pending_ops_.swap(nel_policy_ops);
808     reporting_endpoint_pending_ops_.swap(reporting_endpoint_ops);
809     reporting_endpoint_group_pending_ops_.swap(reporting_endpoint_group_ops);
810     // TODO(chlily): swap out pending operations queue for Reporting reports.
811     op_count = num_pending_;
812     num_pending_ = 0;
813   }
814   if (!db() || op_count == 0)
815     return;
816 
817   sql::Transaction transaction(db());
818   if (!transaction.Begin())
819     return;
820 
821   // Commit all the NEL policy operations.
822   for (const auto& origin_and_nel_policy_ops : nel_policy_ops) {
823     const PendingOperationsVector<NelPolicyInfo>& ops_for_origin =
824         origin_and_nel_policy_ops.second;
825     for (const std::unique_ptr<PendingOperation<NelPolicyInfo>>& nel_policy_op :
826          ops_for_origin) {
827       CommitNelPolicyOperation(nel_policy_op.get());
828     }
829   }
830 
831   // Commit all the Reporting endpoint operations.
832   for (const auto& key_and_reporting_endpoint_ops : reporting_endpoint_ops) {
833     const PendingOperationsVector<ReportingEndpointInfo>& ops_for_key =
834         key_and_reporting_endpoint_ops.second;
835     for (const std::unique_ptr<PendingOperation<ReportingEndpointInfo>>&
836              reporting_endpoint_op : ops_for_key) {
837       CommitReportingEndpointOperation(reporting_endpoint_op.get());
838     }
839   }
840 
841   // Commit all the Reporting endpoint group operations.
842   for (const auto& key_and_reporting_endpoint_group_ops :
843        reporting_endpoint_group_ops) {
844     const PendingOperationsVector<ReportingEndpointGroupInfo>& ops_for_key =
845         key_and_reporting_endpoint_group_ops.second;
846     for (const std::unique_ptr<PendingOperation<ReportingEndpointGroupInfo>>&
847              reporting_endpoint_group_op : ops_for_key) {
848       CommitReportingEndpointGroupOperation(reporting_endpoint_group_op.get());
849     }
850   }
851 
852   // TODO(chlily): Commit operations pertaining to Reporting reports.
853 
854   transaction.Commit();
855 }
856 
CommitNelPolicyOperation(PendingOperation<NelPolicyInfo> * op)857 bool SQLitePersistentReportingAndNelStore::Backend::CommitNelPolicyOperation(
858     PendingOperation<NelPolicyInfo>* op) {
859   DCHECK_EQ(1, db()->transaction_nesting());
860 
861   sql::Statement add_statement(db()->GetCachedStatement(
862       SQL_FROM_HERE,
863       "INSERT INTO nel_policies (nik, origin_scheme, origin_host, origin_port, "
864       "received_ip_address, group_name, expires_us_since_epoch, "
865       "success_fraction, failure_fraction, is_include_subdomains, "
866       "last_access_us_since_epoch) VALUES (?,?,?,?,?,?,?,?,?,?,?)"));
867   if (!add_statement.is_valid())
868     return false;
869 
870   sql::Statement update_access_statement(db()->GetCachedStatement(
871       SQL_FROM_HERE,
872       "UPDATE nel_policies SET last_access_us_since_epoch=? WHERE "
873       "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=?"));
874   if (!update_access_statement.is_valid())
875     return false;
876 
877   sql::Statement del_statement(db()->GetCachedStatement(
878       SQL_FROM_HERE,
879       "DELETE FROM nel_policies WHERE "
880       "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=?"));
881   if (!del_statement.is_valid())
882     return false;
883 
884   const NelPolicyInfo& nel_policy_info = op->data();
885 
886   switch (op->type()) {
887     case PendingOperationType::ADD:
888       add_statement.Reset(true);
889       add_statement.BindString(
890           0, nel_policy_info.network_anonymization_key_string);
891       add_statement.BindString(1, nel_policy_info.origin_scheme);
892       add_statement.BindString(2, nel_policy_info.origin_host);
893       add_statement.BindInt(3, nel_policy_info.origin_port);
894       add_statement.BindString(4, nel_policy_info.received_ip_address);
895       add_statement.BindString(5, nel_policy_info.report_to);
896       add_statement.BindInt64(6, nel_policy_info.expires_us_since_epoch);
897       add_statement.BindDouble(7, nel_policy_info.success_fraction);
898       add_statement.BindDouble(8, nel_policy_info.failure_fraction);
899       add_statement.BindBool(9, nel_policy_info.is_include_subdomains);
900       add_statement.BindInt64(10, nel_policy_info.last_access_us_since_epoch);
901       if (!add_statement.Run()) {
902         DLOG(WARNING) << "Could not add a NEL policy to the DB.";
903         return false;
904       }
905       break;
906 
907     case PendingOperationType::UPDATE_ACCESS_TIME:
908       update_access_statement.Reset(true);
909       update_access_statement.BindInt64(
910           0, nel_policy_info.last_access_us_since_epoch);
911       update_access_statement.BindString(
912           1, nel_policy_info.network_anonymization_key_string);
913       update_access_statement.BindString(2, nel_policy_info.origin_scheme);
914       update_access_statement.BindString(3, nel_policy_info.origin_host);
915       update_access_statement.BindInt(4, nel_policy_info.origin_port);
916       if (!update_access_statement.Run()) {
917         DLOG(WARNING)
918             << "Could not update NEL policy last access time in the DB.";
919         return false;
920       }
921       break;
922 
923     case PendingOperationType::DELETE:
924       del_statement.Reset(true);
925       del_statement.BindString(
926           0, nel_policy_info.network_anonymization_key_string);
927       del_statement.BindString(1, nel_policy_info.origin_scheme);
928       del_statement.BindString(2, nel_policy_info.origin_host);
929       del_statement.BindInt(3, nel_policy_info.origin_port);
930       if (!del_statement.Run()) {
931         DLOG(WARNING) << "Could not delete a NEL policy from the DB.";
932         return false;
933       }
934       break;
935 
936     default:
937       // There are no UPDATE_DETAILS operations for NEL policies.
938       // TODO(chlily): Maybe add the ability to update details as opposed to
939       // removing and re-adding every time; it might be slightly more efficient.
940       NOTREACHED();
941       break;
942   }
943 
944   return true;
945 }
946 
947 bool SQLitePersistentReportingAndNelStore::Backend::
CommitReportingEndpointOperation(PendingOperation<ReportingEndpointInfo> * op)948     CommitReportingEndpointOperation(
949         PendingOperation<ReportingEndpointInfo>* op) {
950   DCHECK_EQ(1, db()->transaction_nesting());
951 
952   sql::Statement add_statement(db()->GetCachedStatement(
953       SQL_FROM_HERE,
954       "INSERT INTO reporting_endpoints (nik, origin_scheme, origin_host, "
955       "origin_port, group_name, url, priority, weight) "
956       "VALUES (?,?,?,?,?,?,?,?)"));
957   if (!add_statement.is_valid())
958     return false;
959 
960   sql::Statement update_details_statement(db()->GetCachedStatement(
961       SQL_FROM_HERE,
962       "UPDATE reporting_endpoints SET priority=?, weight=? WHERE "
963       "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? "
964       "AND group_name=? AND url=?"));
965   if (!update_details_statement.is_valid())
966     return false;
967 
968   sql::Statement del_statement(db()->GetCachedStatement(
969       SQL_FROM_HERE,
970       "DELETE FROM reporting_endpoints WHERE "
971       "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? "
972       "AND group_name=? AND url=?"));
973   if (!del_statement.is_valid())
974     return false;
975 
976   const ReportingEndpointInfo& reporting_endpoint_info = op->data();
977 
978   switch (op->type()) {
979     case PendingOperationType::ADD:
980       add_statement.Reset(true);
981       add_statement.BindString(
982           0, reporting_endpoint_info.network_anonymization_key_string);
983       add_statement.BindString(1, reporting_endpoint_info.origin_scheme);
984       add_statement.BindString(2, reporting_endpoint_info.origin_host);
985       add_statement.BindInt(3, reporting_endpoint_info.origin_port);
986       add_statement.BindString(4, reporting_endpoint_info.group_name);
987       add_statement.BindString(5, reporting_endpoint_info.url);
988       add_statement.BindInt(6, reporting_endpoint_info.priority);
989       add_statement.BindInt(7, reporting_endpoint_info.weight);
990       if (!add_statement.Run()) {
991         DLOG(WARNING) << "Could not add a Reporting endpoint to the DB.";
992         return false;
993       }
994       break;
995 
996     case PendingOperationType::UPDATE_DETAILS:
997       update_details_statement.Reset(true);
998       update_details_statement.BindInt(0, reporting_endpoint_info.priority);
999       update_details_statement.BindInt(1, reporting_endpoint_info.weight);
1000       update_details_statement.BindString(
1001           2, reporting_endpoint_info.network_anonymization_key_string);
1002       update_details_statement.BindString(
1003           3, reporting_endpoint_info.origin_scheme);
1004       update_details_statement.BindString(4,
1005                                           reporting_endpoint_info.origin_host);
1006       update_details_statement.BindInt(5, reporting_endpoint_info.origin_port);
1007       update_details_statement.BindString(6,
1008                                           reporting_endpoint_info.group_name);
1009       update_details_statement.BindString(7, reporting_endpoint_info.url);
1010       if (!update_details_statement.Run()) {
1011         DLOG(WARNING)
1012             << "Could not update Reporting endpoint details in the DB.";
1013         return false;
1014       }
1015       break;
1016 
1017     case PendingOperationType::DELETE:
1018       del_statement.Reset(true);
1019       del_statement.BindString(
1020           0, reporting_endpoint_info.network_anonymization_key_string);
1021       del_statement.BindString(1, reporting_endpoint_info.origin_scheme);
1022       del_statement.BindString(2, reporting_endpoint_info.origin_host);
1023       del_statement.BindInt(3, reporting_endpoint_info.origin_port);
1024       del_statement.BindString(4, reporting_endpoint_info.group_name);
1025       del_statement.BindString(5, reporting_endpoint_info.url);
1026       if (!del_statement.Run()) {
1027         DLOG(WARNING) << "Could not delete a Reporting endpoint from the DB.";
1028         return false;
1029       }
1030       break;
1031 
1032     default:
1033       // There are no UPDATE_ACCESS_TIME operations for Reporting endpoints
1034       // because their access times are not tracked.
1035       NOTREACHED();
1036       break;
1037   }
1038 
1039   return true;
1040 }
1041 
1042 bool SQLitePersistentReportingAndNelStore::Backend::
CommitReportingEndpointGroupOperation(PendingOperation<ReportingEndpointGroupInfo> * op)1043     CommitReportingEndpointGroupOperation(
1044         PendingOperation<ReportingEndpointGroupInfo>* op) {
1045   DCHECK_EQ(1, db()->transaction_nesting());
1046 
1047   sql::Statement add_statement(db()->GetCachedStatement(
1048       SQL_FROM_HERE,
1049       "INSERT INTO reporting_endpoint_groups (nik, origin_scheme, origin_host, "
1050       "origin_port, group_name, is_include_subdomains, expires_us_since_epoch, "
1051       "last_access_us_since_epoch) VALUES (?,?,?,?,?,?,?,?)"));
1052   if (!add_statement.is_valid())
1053     return false;
1054 
1055   sql::Statement update_access_statement(db()->GetCachedStatement(
1056       SQL_FROM_HERE,
1057       "UPDATE reporting_endpoint_groups SET last_access_us_since_epoch=? WHERE "
1058       "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? AND "
1059       "group_name=?"));
1060   if (!update_access_statement.is_valid())
1061     return false;
1062 
1063   sql::Statement update_details_statement(db()->GetCachedStatement(
1064       SQL_FROM_HERE,
1065       "UPDATE reporting_endpoint_groups SET is_include_subdomains=?, "
1066       "expires_us_since_epoch=?, last_access_us_since_epoch=? WHERE "
1067       "nik=? AND origin_scheme=? AND origin_host=? AND origin_port=? AND "
1068       "group_name=?"));
1069   if (!update_details_statement.is_valid())
1070     return false;
1071 
1072   sql::Statement del_statement(
1073       db()->GetCachedStatement(SQL_FROM_HERE,
1074                                "DELETE FROM reporting_endpoint_groups WHERE "
1075                                "nik=? AND origin_scheme=? AND origin_host=? "
1076                                "AND origin_port=? AND group_name=?"));
1077   if (!del_statement.is_valid())
1078     return false;
1079 
1080   const ReportingEndpointGroupInfo& reporting_endpoint_group_info = op->data();
1081 
1082   switch (op->type()) {
1083     case PendingOperationType::ADD:
1084       add_statement.Reset(true);
1085       add_statement.BindString(
1086           0, reporting_endpoint_group_info.network_anonymization_key_string);
1087       add_statement.BindString(1, reporting_endpoint_group_info.origin_scheme);
1088       add_statement.BindString(2, reporting_endpoint_group_info.origin_host);
1089       add_statement.BindInt(3, reporting_endpoint_group_info.origin_port);
1090       add_statement.BindString(4, reporting_endpoint_group_info.group_name);
1091       add_statement.BindBool(
1092           5, reporting_endpoint_group_info.is_include_subdomains);
1093       add_statement.BindInt64(
1094           6, reporting_endpoint_group_info.expires_us_since_epoch);
1095       add_statement.BindInt64(
1096           7, reporting_endpoint_group_info.last_access_us_since_epoch);
1097       if (!add_statement.Run()) {
1098         DLOG(WARNING) << "Could not add a Reporting endpoint group to the DB.";
1099         return false;
1100       }
1101       break;
1102 
1103     case PendingOperationType::UPDATE_ACCESS_TIME:
1104       update_access_statement.Reset(true);
1105       update_access_statement.BindInt64(
1106           0, reporting_endpoint_group_info.last_access_us_since_epoch);
1107       update_access_statement.BindString(
1108           1, reporting_endpoint_group_info.network_anonymization_key_string);
1109       update_access_statement.BindString(
1110           2, reporting_endpoint_group_info.origin_scheme);
1111       update_access_statement.BindString(
1112           3, reporting_endpoint_group_info.origin_host);
1113       update_access_statement.BindInt(
1114           4, reporting_endpoint_group_info.origin_port);
1115       update_access_statement.BindString(
1116           5, reporting_endpoint_group_info.group_name);
1117       if (!update_access_statement.Run()) {
1118         DLOG(WARNING)
1119             << "Could not update Reporting endpoint group last access "
1120                "time in the DB.";
1121         return false;
1122       }
1123       break;
1124 
1125     case PendingOperationType::UPDATE_DETAILS:
1126       update_details_statement.Reset(true);
1127       update_details_statement.BindBool(
1128           0, reporting_endpoint_group_info.is_include_subdomains);
1129       update_details_statement.BindInt64(
1130           1, reporting_endpoint_group_info.expires_us_since_epoch);
1131       update_details_statement.BindInt64(
1132           2, reporting_endpoint_group_info.last_access_us_since_epoch);
1133       update_details_statement.BindString(
1134           3, reporting_endpoint_group_info.network_anonymization_key_string);
1135       update_details_statement.BindString(
1136           4, reporting_endpoint_group_info.origin_scheme);
1137       update_details_statement.BindString(
1138           5, reporting_endpoint_group_info.origin_host);
1139       update_details_statement.BindInt(
1140           6, reporting_endpoint_group_info.origin_port);
1141       update_details_statement.BindString(
1142           7, reporting_endpoint_group_info.group_name);
1143       if (!update_details_statement.Run()) {
1144         DLOG(WARNING)
1145             << "Could not update Reporting endpoint group details in the DB.";
1146         return false;
1147       }
1148       break;
1149 
1150     case PendingOperationType::DELETE:
1151       del_statement.Reset(true);
1152       del_statement.BindString(
1153           0, reporting_endpoint_group_info.network_anonymization_key_string);
1154       del_statement.BindString(1, reporting_endpoint_group_info.origin_scheme);
1155       del_statement.BindString(2, reporting_endpoint_group_info.origin_host);
1156       del_statement.BindInt(3, reporting_endpoint_group_info.origin_port);
1157       del_statement.BindString(4, reporting_endpoint_group_info.group_name);
1158       if (!del_statement.Run()) {
1159         DLOG(WARNING)
1160             << "Could not delete a Reporting endpoint group from the DB.";
1161         return false;
1162       }
1163       break;
1164   }
1165 
1166   return true;
1167 }
1168 
1169 template <typename KeyType, typename DataType>
BatchOperation(KeyType key,std::unique_ptr<PendingOperation<DataType>> po,QueueType<KeyType,DataType> * queue)1170 void SQLitePersistentReportingAndNelStore::Backend::BatchOperation(
1171     KeyType key,
1172     std::unique_ptr<PendingOperation<DataType>> po,
1173     QueueType<KeyType, DataType>* queue) {
1174   DCHECK(!background_task_runner()->RunsTasksInCurrentSequence());
1175 
1176   size_t num_pending;
1177   {
1178     base::AutoLock locked(lock_);
1179 
1180     std::pair<typename QueueType<KeyType, DataType>::iterator, bool>
1181         iter_and_result = queue->insert(std::make_pair(
1182             std::move(key), PendingOperationsVector<DataType>()));
1183     PendingOperationsVector<DataType>* ops_for_key =
1184         &iter_and_result.first->second;
1185     // If the insert failed, then we already have operations for this
1186     // key, so we try to coalesce the new operation with the existing ones.
1187     if (!iter_and_result.second)
1188       MaybeCoalesceOperations(ops_for_key, po.get());
1189     ops_for_key->push_back(std::move(po));
1190     // Note that num_pending_ counts number of calls to Batch*Operation(), not
1191     // the current length of the queue; this is intentional to guarantee
1192     // progress, as the length of the queue may decrease in some cases.
1193     num_pending = ++num_pending_;
1194   }
1195 
1196   OnOperationBatched(num_pending);
1197 }
1198 
1199 template <typename DataType>
MaybeCoalesceOperations(PendingOperationsVector<DataType> * ops_for_key,PendingOperation<DataType> * new_op)1200 void SQLitePersistentReportingAndNelStore::Backend::MaybeCoalesceOperations(
1201     PendingOperationsVector<DataType>* ops_for_key,
1202     PendingOperation<DataType>* new_op) {
1203   DCHECK(!ops_for_key->empty());
1204 
1205   switch (new_op->type()) {
1206     case PendingOperationType::DELETE:
1207       // A delete makes all previous operations irrelevant.
1208       ops_for_key->clear();
1209       break;
1210 
1211     case PendingOperationType::UPDATE_ACCESS_TIME:
1212       if (ops_for_key->back()->type() ==
1213           PendingOperationType::UPDATE_ACCESS_TIME) {
1214         // Updating the access time twice in a row is equivalent to just the
1215         // latter update.
1216         ops_for_key->pop_back();
1217       }
1218       break;
1219 
1220     case PendingOperationType::UPDATE_DETAILS:
1221       while (!ops_for_key->empty() &&
1222              // Updating the details twice in a row is equivalent to just the
1223              // latter update.
1224              (ops_for_key->back()->type() ==
1225                   PendingOperationType::UPDATE_DETAILS ||
1226               // UPDATE_DETAILS also updates the access time, so either type of
1227               // update operation can be discarded.
1228               ops_for_key->back()->type() ==
1229                   PendingOperationType::UPDATE_ACCESS_TIME)) {
1230         ops_for_key->pop_back();
1231       }
1232       break;
1233 
1234     case PendingOperationType::ADD:
1235       // Nothing special is done for an add operation. If it is overwriting an
1236       // existing entry, it will be preceded by at most one delete.
1237       DCHECK_LE(ops_for_key->size(), 1u);
1238       break;
1239   }
1240 }
1241 
OnOperationBatched(size_t num_pending)1242 void SQLitePersistentReportingAndNelStore::Backend::OnOperationBatched(
1243     size_t num_pending) {
1244   DCHECK(!background_task_runner()->RunsTasksInCurrentSequence());
1245   // Commit every 30 seconds.
1246   static const int kCommitIntervalMs = 30 * 1000;
1247   // Commit right away if we have more than 512 outstanding operations.
1248   static const size_t kCommitAfterBatchSize = 512;
1249 
1250   if (num_pending == 1) {
1251     // We've gotten our first entry for this batch, fire off the timer.
1252     if (!background_task_runner()->PostDelayedTask(
1253             FROM_HERE, base::BindOnce(&Backend::Commit, this),
1254             base::Milliseconds(kCommitIntervalMs))) {
1255       NOTREACHED() << "background_task_runner_ is not running.";
1256     }
1257   } else if (num_pending >= kCommitAfterBatchSize) {
1258     // We've reached a big enough batch, fire off a commit now.
1259     PostBackgroundTask(FROM_HERE, base::BindOnce(&Backend::Commit, this));
1260   }
1261 }
1262 
1263 // TODO(chlily): Discard expired policies when loading, discard and record
1264 // problem if loaded policy is malformed.
1265 void SQLitePersistentReportingAndNelStore::Backend::
LoadNelPoliciesAndNotifyInBackground(NelPoliciesLoadedCallback loaded_callback)1266     LoadNelPoliciesAndNotifyInBackground(
1267         NelPoliciesLoadedCallback loaded_callback) {
1268   DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
1269 
1270   std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies;
1271   if (!InitializeDatabase()) {
1272     PostClientTask(
1273         FROM_HERE,
1274         base::BindOnce(&Backend::CompleteLoadNelPoliciesAndNotifyInForeground,
1275                        this, std::move(loaded_callback),
1276                        std::move(loaded_policies), false /* load_success */));
1277     return;
1278   }
1279 
1280   sql::Statement smt(db()->GetUniqueStatement(
1281       "SELECT nik, origin_scheme, origin_host, origin_port, "
1282       "received_ip_address, group_name, expires_us_since_epoch, "
1283       "success_fraction, failure_fraction, is_include_subdomains, "
1284       "last_access_us_since_epoch FROM nel_policies"));
1285   if (!smt.is_valid()) {
1286     Reset();
1287     PostClientTask(
1288         FROM_HERE,
1289         base::BindOnce(&Backend::CompleteLoadNelPoliciesAndNotifyInForeground,
1290                        this, std::move(loaded_callback),
1291                        std::move(loaded_policies), false /* load_success */));
1292     return;
1293   }
1294 
1295   while (smt.Step()) {
1296     // Attempt to reconstitute a NEL policy from the fields stored in the
1297     // database.
1298     NetworkAnonymizationKey network_anonymization_key;
1299     if (!NetworkAnonymizationKeyFromString(smt.ColumnString(0),
1300                                            &network_anonymization_key))
1301       continue;
1302     NetworkErrorLoggingService::NelPolicy policy;
1303     policy.key = NetworkErrorLoggingService::NelPolicyKey(
1304         network_anonymization_key,
1305         url::Origin::CreateFromNormalizedTuple(
1306             /* origin_scheme = */ smt.ColumnString(1),
1307             /* origin_host = */ smt.ColumnString(2),
1308             /* origin_port = */ smt.ColumnInt(3)));
1309     if (!policy.received_ip_address.AssignFromIPLiteral(smt.ColumnString(4)))
1310       policy.received_ip_address = IPAddress();
1311     policy.report_to = smt.ColumnString(5);
1312     policy.expires = base::Time::FromDeltaSinceWindowsEpoch(
1313         base::Microseconds(smt.ColumnInt64(6)));
1314     policy.success_fraction = smt.ColumnDouble(7);
1315     policy.failure_fraction = smt.ColumnDouble(8);
1316     policy.include_subdomains = smt.ColumnBool(9);
1317     policy.last_used = base::Time::FromDeltaSinceWindowsEpoch(
1318         base::Microseconds(smt.ColumnInt64(10)));
1319 
1320     loaded_policies.push_back(std::move(policy));
1321   }
1322 
1323   PostClientTask(
1324       FROM_HERE,
1325       base::BindOnce(&Backend::CompleteLoadNelPoliciesAndNotifyInForeground,
1326                      this, std::move(loaded_callback),
1327                      std::move(loaded_policies), true /* load_success */));
1328 }
1329 
1330 void SQLitePersistentReportingAndNelStore::Backend::
CompleteLoadNelPoliciesAndNotifyInForeground(NelPoliciesLoadedCallback loaded_callback,std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies,bool load_success)1331     CompleteLoadNelPoliciesAndNotifyInForeground(
1332         NelPoliciesLoadedCallback loaded_callback,
1333         std::vector<NetworkErrorLoggingService::NelPolicy> loaded_policies,
1334         bool load_success) {
1335   DCHECK(client_task_runner()->RunsTasksInCurrentSequence());
1336 
1337   if (load_success) {
1338     RecordNumberOfLoadedNelPolicies(loaded_policies.size());
1339   } else {
1340     DCHECK(loaded_policies.empty());
1341   }
1342 
1343   std::move(loaded_callback).Run(std::move(loaded_policies));
1344 }
1345 
1346 void SQLitePersistentReportingAndNelStore::Backend::
LoadReportingClientsAndNotifyInBackground(ReportingClientsLoadedCallback loaded_callback)1347     LoadReportingClientsAndNotifyInBackground(
1348         ReportingClientsLoadedCallback loaded_callback) {
1349   DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
1350 
1351   std::vector<ReportingEndpoint> loaded_endpoints;
1352   std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups;
1353   if (!InitializeDatabase()) {
1354     PostClientTask(
1355         FROM_HERE,
1356         base::BindOnce(
1357             &Backend::CompleteLoadReportingClientsAndNotifyInForeground, this,
1358             std::move(loaded_callback), std::move(loaded_endpoints),
1359             std::move(loaded_endpoint_groups), false /* load_success */));
1360     return;
1361   }
1362 
1363   sql::Statement endpoints_statement(db()->GetUniqueStatement(
1364       "SELECT nik, origin_scheme, origin_host, origin_port, group_name, "
1365       "url, priority, weight FROM reporting_endpoints"));
1366   sql::Statement endpoint_groups_statement(db()->GetUniqueStatement(
1367       "SELECT nik, origin_scheme, origin_host, origin_port, group_name, "
1368       "is_include_subdomains, expires_us_since_epoch, "
1369       "last_access_us_since_epoch FROM reporting_endpoint_groups"));
1370   if (!endpoints_statement.is_valid() ||
1371       !endpoint_groups_statement.is_valid()) {
1372     Reset();
1373     PostClientTask(
1374         FROM_HERE,
1375         base::BindOnce(
1376             &Backend::CompleteLoadReportingClientsAndNotifyInForeground, this,
1377             std::move(loaded_callback), std::move(loaded_endpoints),
1378             std::move(loaded_endpoint_groups), false /* load_success */));
1379     return;
1380   }
1381 
1382   while (endpoints_statement.Step()) {
1383     // Attempt to reconstitute a ReportingEndpoint from the fields stored in the
1384     // database.
1385     NetworkAnonymizationKey network_anonymization_key;
1386     if (!NetworkAnonymizationKeyFromString(endpoints_statement.ColumnString(0),
1387                                            &network_anonymization_key))
1388       continue;
1389     ReportingEndpointGroupKey group_key(
1390         network_anonymization_key,
1391         /* origin = */
1392         url::Origin::CreateFromNormalizedTuple(
1393             /* origin_scheme = */ endpoints_statement.ColumnString(1),
1394             /* origin_host = */ endpoints_statement.ColumnString(2),
1395             /* origin_port = */ endpoints_statement.ColumnInt(3)),
1396         /* group_name = */ endpoints_statement.ColumnString(4));
1397     ReportingEndpoint::EndpointInfo endpoint_info;
1398     endpoint_info.url = GURL(endpoints_statement.ColumnString(5));
1399     endpoint_info.priority = endpoints_statement.ColumnInt(6);
1400     endpoint_info.weight = endpoints_statement.ColumnInt(7);
1401 
1402     loaded_endpoints.emplace_back(std::move(group_key),
1403                                   std::move(endpoint_info));
1404   }
1405 
1406   while (endpoint_groups_statement.Step()) {
1407     // Attempt to reconstitute a CachedReportingEndpointGroup from the fields
1408     // stored in the database.
1409     NetworkAnonymizationKey network_anonymization_key;
1410     if (!NetworkAnonymizationKeyFromString(
1411             endpoint_groups_statement.ColumnString(0),
1412             &network_anonymization_key))
1413       continue;
1414     ReportingEndpointGroupKey group_key(
1415         network_anonymization_key,
1416         /* origin = */
1417         url::Origin::CreateFromNormalizedTuple(
1418             /* origin_scheme = */ endpoint_groups_statement.ColumnString(1),
1419             /* origin_host = */ endpoint_groups_statement.ColumnString(2),
1420             /* origin_port = */ endpoint_groups_statement.ColumnInt(3)),
1421         /* group_name = */ endpoint_groups_statement.ColumnString(4));
1422     OriginSubdomains include_subdomains =
1423         endpoint_groups_statement.ColumnBool(5) ? OriginSubdomains::INCLUDE
1424                                                 : OriginSubdomains::EXCLUDE;
1425     base::Time expires = base::Time::FromDeltaSinceWindowsEpoch(
1426         base::Microseconds(endpoint_groups_statement.ColumnInt64(6)));
1427     base::Time last_used = base::Time::FromDeltaSinceWindowsEpoch(
1428         base::Microseconds(endpoint_groups_statement.ColumnInt64(7)));
1429 
1430     loaded_endpoint_groups.emplace_back(std::move(group_key),
1431                                         include_subdomains, expires, last_used);
1432   }
1433 
1434   PostClientTask(
1435       FROM_HERE,
1436       base::BindOnce(
1437           &Backend::CompleteLoadReportingClientsAndNotifyInForeground, this,
1438           std::move(loaded_callback), std::move(loaded_endpoints),
1439           std::move(loaded_endpoint_groups), true /* load_success */));
1440 }
1441 
1442 void SQLitePersistentReportingAndNelStore::Backend::
CompleteLoadReportingClientsAndNotifyInForeground(ReportingClientsLoadedCallback loaded_callback,std::vector<ReportingEndpoint> loaded_endpoints,std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups,bool load_success)1443     CompleteLoadReportingClientsAndNotifyInForeground(
1444         ReportingClientsLoadedCallback loaded_callback,
1445         std::vector<ReportingEndpoint> loaded_endpoints,
1446         std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups,
1447         bool load_success) {
1448   DCHECK(client_task_runner()->RunsTasksInCurrentSequence());
1449 
1450   if (load_success) {
1451     RecordNumberOfLoadedReportingEndpoints(loaded_endpoints.size());
1452     RecordNumberOfLoadedReportingEndpointGroups(loaded_endpoint_groups.size());
1453   } else {
1454     DCHECK(loaded_endpoints.empty());
1455     DCHECK(loaded_endpoint_groups.empty());
1456   }
1457 
1458   std::move(loaded_callback)
1459       .Run(std::move(loaded_endpoints), std::move(loaded_endpoint_groups));
1460 }
1461 
1462 void SQLitePersistentReportingAndNelStore::Backend::
RecordNumberOfLoadedNelPolicies(size_t count)1463     RecordNumberOfLoadedNelPolicies(size_t count) {
1464   // The NetworkErrorLoggingService stores up to 1000 policies.
1465   UMA_HISTOGRAM_COUNTS_1000(kNumberOfLoadedNelPoliciesHistogramName, count);
1466   // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
1467   UMA_HISTOGRAM_COUNTS_10000(kNumberOfLoadedNelPolicies2HistogramName, count);
1468 }
1469 
1470 void SQLitePersistentReportingAndNelStore::Backend::
RecordNumberOfLoadedReportingEndpoints(size_t count)1471     RecordNumberOfLoadedReportingEndpoints(size_t count) {
1472   // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
1473   UMA_HISTOGRAM_COUNTS_10000(kNumberOfLoadedReportingEndpoints2HistogramName,
1474                              count);
1475 }
1476 
1477 void SQLitePersistentReportingAndNelStore::Backend::
RecordNumberOfLoadedReportingEndpointGroups(size_t count)1478     RecordNumberOfLoadedReportingEndpointGroups(size_t count) {
1479   // TODO(crbug.com/1165308): Remove this metric once the investigation is done.
1480   UMA_HISTOGRAM_COUNTS_10000(
1481       kNumberOfLoadedReportingEndpointGroups2HistogramName, count);
1482 }
1483 
SQLitePersistentReportingAndNelStore(const base::FilePath & path,const scoped_refptr<base::SequencedTaskRunner> & client_task_runner,const scoped_refptr<base::SequencedTaskRunner> & background_task_runner)1484 SQLitePersistentReportingAndNelStore::SQLitePersistentReportingAndNelStore(
1485     const base::FilePath& path,
1486     const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
1487     const scoped_refptr<base::SequencedTaskRunner>& background_task_runner)
1488     : backend_(base::MakeRefCounted<Backend>(path,
1489                                              client_task_runner,
1490                                              background_task_runner)) {}
1491 
~SQLitePersistentReportingAndNelStore()1492 SQLitePersistentReportingAndNelStore::~SQLitePersistentReportingAndNelStore() {
1493   backend_->Close();
1494 }
1495 
LoadNelPolicies(NelPoliciesLoadedCallback loaded_callback)1496 void SQLitePersistentReportingAndNelStore::LoadNelPolicies(
1497     NelPoliciesLoadedCallback loaded_callback) {
1498   DCHECK(!loaded_callback.is_null());
1499   backend_->LoadNelPolicies(base::BindOnce(
1500       &SQLitePersistentReportingAndNelStore::CompleteLoadNelPolicies,
1501       weak_factory_.GetWeakPtr(), std::move(loaded_callback)));
1502 }
1503 
AddNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)1504 void SQLitePersistentReportingAndNelStore::AddNelPolicy(
1505     const NetworkErrorLoggingService::NelPolicy& policy) {
1506   backend_->AddNelPolicy(policy);
1507 }
1508 
UpdateNelPolicyAccessTime(const NetworkErrorLoggingService::NelPolicy & policy)1509 void SQLitePersistentReportingAndNelStore::UpdateNelPolicyAccessTime(
1510     const NetworkErrorLoggingService::NelPolicy& policy) {
1511   backend_->UpdateNelPolicyAccessTime(policy);
1512 }
1513 
DeleteNelPolicy(const NetworkErrorLoggingService::NelPolicy & policy)1514 void SQLitePersistentReportingAndNelStore::DeleteNelPolicy(
1515     const NetworkErrorLoggingService::NelPolicy& policy) {
1516   backend_->DeleteNelPolicy(policy);
1517 }
1518 
LoadReportingClients(ReportingClientsLoadedCallback loaded_callback)1519 void SQLitePersistentReportingAndNelStore::LoadReportingClients(
1520     ReportingClientsLoadedCallback loaded_callback) {
1521   DCHECK(!loaded_callback.is_null());
1522   backend_->LoadReportingClients(base::BindOnce(
1523       &SQLitePersistentReportingAndNelStore::CompleteLoadReportingClients,
1524       weak_factory_.GetWeakPtr(), std::move(loaded_callback)));
1525 }
1526 
AddReportingEndpoint(const ReportingEndpoint & endpoint)1527 void SQLitePersistentReportingAndNelStore::AddReportingEndpoint(
1528     const ReportingEndpoint& endpoint) {
1529   backend_->AddReportingEndpoint(endpoint);
1530 }
1531 
AddReportingEndpointGroup(const CachedReportingEndpointGroup & group)1532 void SQLitePersistentReportingAndNelStore::AddReportingEndpointGroup(
1533     const CachedReportingEndpointGroup& group) {
1534   backend_->AddReportingEndpointGroup(group);
1535 }
1536 
1537 void SQLitePersistentReportingAndNelStore::
UpdateReportingEndpointGroupAccessTime(const CachedReportingEndpointGroup & group)1538     UpdateReportingEndpointGroupAccessTime(
1539         const CachedReportingEndpointGroup& group) {
1540   backend_->UpdateReportingEndpointGroupAccessTime(group);
1541 }
1542 
UpdateReportingEndpointDetails(const ReportingEndpoint & endpoint)1543 void SQLitePersistentReportingAndNelStore::UpdateReportingEndpointDetails(
1544     const ReportingEndpoint& endpoint) {
1545   backend_->UpdateReportingEndpointDetails(endpoint);
1546 }
1547 
UpdateReportingEndpointGroupDetails(const CachedReportingEndpointGroup & group)1548 void SQLitePersistentReportingAndNelStore::UpdateReportingEndpointGroupDetails(
1549     const CachedReportingEndpointGroup& group) {
1550   backend_->UpdateReportingEndpointGroupDetails(group);
1551 }
1552 
DeleteReportingEndpoint(const ReportingEndpoint & endpoint)1553 void SQLitePersistentReportingAndNelStore::DeleteReportingEndpoint(
1554     const ReportingEndpoint& endpoint) {
1555   backend_->DeleteReportingEndpoint(endpoint);
1556 }
1557 
DeleteReportingEndpointGroup(const CachedReportingEndpointGroup & group)1558 void SQLitePersistentReportingAndNelStore::DeleteReportingEndpointGroup(
1559     const CachedReportingEndpointGroup& group) {
1560   backend_->DeleteReportingEndpointGroup(group);
1561 }
1562 
Flush()1563 void SQLitePersistentReportingAndNelStore::Flush() {
1564   backend_->Flush(base::DoNothing());
1565 }
1566 
GetQueueLengthForTesting() const1567 size_t SQLitePersistentReportingAndNelStore::GetQueueLengthForTesting() const {
1568   return backend_->GetQueueLengthForTesting();
1569 }
1570 
CompleteLoadNelPolicies(NelPoliciesLoadedCallback callback,std::vector<NetworkErrorLoggingService::NelPolicy> policies)1571 void SQLitePersistentReportingAndNelStore::CompleteLoadNelPolicies(
1572     NelPoliciesLoadedCallback callback,
1573     std::vector<NetworkErrorLoggingService::NelPolicy> policies) {
1574   std::move(callback).Run(std::move(policies));
1575 }
1576 
CompleteLoadReportingClients(ReportingClientsLoadedCallback callback,std::vector<ReportingEndpoint> endpoints,std::vector<CachedReportingEndpointGroup> endpoint_groups)1577 void SQLitePersistentReportingAndNelStore::CompleteLoadReportingClients(
1578     ReportingClientsLoadedCallback callback,
1579     std::vector<ReportingEndpoint> endpoints,
1580     std::vector<CachedReportingEndpointGroup> endpoint_groups) {
1581   std::move(callback).Run(std::move(endpoints), std::move(endpoint_groups));
1582 }
1583 
1584 }  // namespace net
1585