blob: 0517645b2f1fb8a3f772ba0520dc023992600454 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_CONVERSIONS_CONVERSION_REPORTER_IMPL_H_
#define CONTENT_BROWSER_CONVERSIONS_CONVERSION_REPORTER_IMPL_H_
#include <stdint.h>
#include <memory>
#include <queue>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/browser/conversions/conversion_manager_impl.h"
#include "content/browser/conversions/conversion_report.h"
#include "content/common/content_export.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace base {
class Clock;
} // namespace base
namespace content {
class ConversionManager;
class StoragePartition;
// This class is responsible for managing the dispatch of conversion reports to
// a ConversionReporterImpl::NetworkSender. It maintains a queue of reports and
// a timer to ensure all reports are sent at the correct time, since the time in
// which a conversion report is sent is potentially sensitive information.
// Created and owned by ConversionManager.
class CONTENT_EXPORT ConversionReporterImpl
: public ConversionManagerImpl::ConversionReporter {
public:
// This class is responsible for sending conversion reports to their
// configured endpoints over the network.
class NetworkSender {
public:
virtual ~NetworkSender() = default;
// Callback used to notify caller that the requested report has been sent.
using ReportSentCallback = base::OnceCallback<void()>;
// Generates and sends a conversion report matching |report|. This should
// generate a secure POST quest with no-credentials. Does not persist the
// raw pointer.
virtual void SendReport(ConversionReport* report,
ReportSentCallback sent_callback) = 0;
};
ConversionReporterImpl(StoragePartition* storage_partition,
ConversionManager* manager,
const base::Clock* clock);
ConversionReporterImpl(const ConversionReporterImpl&) = delete;
ConversionReporterImpl& operator=(const ConversionReporterImpl&) = delete;
~ConversionReporterImpl() override;
// ConversionManagerImpl::ConversionReporter:
void AddReportsToQueue(std::vector<ConversionReport> reports) override;
void SetNetworkSenderForTesting(
std::unique_ptr<NetworkSender> network_sender);
private:
void MaybeScheduleNextReport();
void SendNextReport();
// Called when a conversion report sent via NetworkSender::SendReport() has
// completed loading.
void OnReportSent(int64_t conversion_id);
// Comparator used to order ConversionReports by their report time, with the
// smallest time at the top of |report_queue_|.
struct ReportComparator {
bool operator()(const std::unique_ptr<ConversionReport>& a,
const std::unique_ptr<ConversionReport>& b) const;
};
// Priority queue which holds reports that are yet to be sent. Reports are
// removed from the queue when they are delivered to the NetworkSender.
std::priority_queue<std::unique_ptr<ConversionReport>,
std::vector<std::unique_ptr<ConversionReport>>,
ReportComparator>
report_queue_;
// Set of all conversion ids that are currently in |report_queue| or are being
// sent by |network_sender_|. The number of concurrent conversion reports
// being sent at any time is expected to be small, so a flat_set is used.
base::flat_set<int64_t> conversion_ids_being_processed_;
// Must outlive |this|.
ConversionManager* conversion_manager_;
const base::Clock* clock_;
// Timer which signals the next report in |report_queue_| should be sent.
base::OneShotTimer send_report_timer_;
// Responsible for issuing requests to network for report that need to be
// sent. Calls OnReportSent() when a report has finished sending.
//
// Should never be nullptr.
std::unique_ptr<NetworkSender> network_sender_;
};
} // namespace content
#endif // CONTENT_BROWSER_CONVERSIONS_CONVERSION_REPORTER_IMPL_H_