blob: 1fd2b3183161e3760f46d87ee4ba5f02dd51d475 [file] [log] [blame]
// 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.
#include "content/browser/aggregation_service/aggregation_service_impl.h"
#include <stdint.h>
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/check_op.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/task/lazy_thread_pool_task_runner.h"
#include "base/task/task_traits.h"
#include "base/time/default_clock.h"
#include "content/browser/aggregation_service/aggregatable_report_assembler.h"
#include "content/browser/aggregation_service/aggregation_service_storage_sql.h"
#include "content/browser/storage_partition_impl.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace content {
namespace {
// The shared task runner for all aggregation service storage operations. Note
// that different AggregationServiceImpl instances perform operations on the
// same task runner. This prevents any potential races when a given storage
// context is destroyed and recreated using the same backing storage. This uses
// BLOCK_SHUTDOWN as some data deletion operations may be running when the
// browser is closed, and we want to ensure all data is deleted correctly.
base::LazyThreadPoolSequencedTaskRunner g_storage_task_runner =
LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
base::TaskTraits(base::TaskPriority::BEST_EFFORT,
base::MayBlock(),
base::TaskShutdownBehavior::BLOCK_SHUTDOWN));
} // namespace
AggregationServiceImpl::AggregationServiceImpl(
bool run_in_memory,
const base::FilePath& user_data_directory,
StoragePartitionImpl* storage_partition)
: AggregationServiceImpl(
run_in_memory,
user_data_directory,
base::DefaultClock::GetInstance(),
std::make_unique<AggregatableReportAssembler>(this,
storage_partition)) {}
AggregationServiceImpl::~AggregationServiceImpl() = default;
// static
std::unique_ptr<AggregationServiceImpl>
AggregationServiceImpl::CreateForTesting(
bool run_in_memory,
const base::FilePath& user_data_directory,
const base::Clock* clock,
std::unique_ptr<AggregatableReportAssembler> assembler) {
return base::WrapUnique<AggregationServiceImpl>(new AggregationServiceImpl(
run_in_memory, user_data_directory, clock, std::move(assembler)));
}
AggregationServiceImpl::AggregationServiceImpl(
bool run_in_memory,
const base::FilePath& user_data_directory,
const base::Clock* clock,
std::unique_ptr<AggregatableReportAssembler> assembler)
: key_storage_(base::SequenceBound<AggregationServiceStorageSql>(
g_storage_task_runner.Get(),
run_in_memory,
user_data_directory,
clock)),
assembler_(std::move(assembler)) {}
void AggregationServiceImpl::AssembleReport(
AggregatableReportRequest report_request,
AssemblyCallback callback) {
// `assembler_` is owned by `this`, so `base::Unretained()` is safe.
assembler_->AssembleReport(
std::move(report_request),
base::BindOnce(&AggregationServiceImpl::OnAssembleReportComplete,
base::Unretained(this), std::move(callback)));
}
const base::SequenceBound<AggregationServiceKeyStorage>&
AggregationServiceImpl::GetKeyStorage() {
return key_storage_;
}
void AggregationServiceImpl::OnAssembleReportComplete(
AssemblyCallback callback,
absl::optional<AggregatableReport> report,
AggregatableReportAssembler::AssemblyStatus status) {
DCHECK_EQ(report.has_value(),
status == AggregatableReportAssembler::AssemblyStatus::kOk);
std::move(callback).Run(std::move(report), status);
}
} // namespace content