Commit 48f489e9 authored by juliatuttle's avatar juliatuttle Committed by Commit bot

Reporting: Add Observer interface to observe cache updates.

Reporting is a spec for delivering out-of-band reports from various
other parts of the browser. See http://wicg.github.io/reporting/ for
the spec, or https://goo.gl/pygX5I for details of the planned
implementation in Chromium.

This adds an Observer interface by which parts of Reporting can observe
cache updates. Expected users are the DeliveryAgent and Serializer.

BUG=704259

Review-Url: https://codereview.chromium.org/2778373003
Cr-Commit-Position: refs/heads/master@{#462980}
parent 11ac780e
......@@ -1411,6 +1411,8 @@ component("net") {
"reporting/reporting_endpoint_manager.h",
"reporting/reporting_header_parser.cc",
"reporting/reporting_header_parser.h",
"reporting/reporting_observer.cc",
"reporting/reporting_observer.h",
"reporting/reporting_policy.cc",
"reporting/reporting_policy.h",
"reporting/reporting_report.cc",
......
......@@ -14,6 +14,7 @@
#include "base/stl_util.h"
#include "base/time/time.h"
#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_context.h"
#include "net/reporting/reporting_report.h"
#include "url/gurl.h"
......@@ -37,6 +38,8 @@ void ReportingCache::AddReport(const GURL& url,
auto inserted =
reports_.insert(std::make_pair(report.get(), std::move(report)));
DCHECK(inserted.second);
context_->NotifyCacheUpdated();
}
void ReportingCache::GetReports(
......@@ -78,6 +81,8 @@ void ReportingCache::IncrementReportsAttempts(
DCHECK(base::ContainsKey(reports_, report));
reports_[report]->attempts++;
}
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveReports(
......@@ -91,6 +96,8 @@ void ReportingCache::RemoveReports(
reports_.erase(report);
}
}
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveAllReports() {
......@@ -107,6 +114,8 @@ void ReportingCache::RemoveAllReports() {
for (auto& it : reports_to_remove)
reports_.erase(it);
context_->NotifyCacheUpdated();
}
void ReportingCache::GetClients(
......@@ -142,6 +151,8 @@ void ReportingCache::SetClient(const url::Origin& origin,
clients_[origin][endpoint] = base::MakeUnique<ReportingClient>(
origin, endpoint, subdomains, group, expires);
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveClients(
......@@ -151,6 +162,8 @@ void ReportingCache::RemoveClients(
DCHECK(clients_[client->origin][client->endpoint].get() == client);
clients_[client->origin].erase(client->endpoint);
}
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin,
......@@ -158,15 +171,21 @@ void ReportingCache::RemoveClientForOriginAndEndpoint(const url::Origin& origin,
DCHECK(base::ContainsKey(clients_, origin));
DCHECK(base::ContainsKey(clients_[origin], endpoint));
clients_[origin].erase(endpoint);
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveClientsForEndpoint(const GURL& endpoint) {
for (auto& it : clients_)
it.second.erase(endpoint);
context_->NotifyCacheUpdated();
}
void ReportingCache::RemoveAllClients() {
clients_.clear();
context_->NotifyCacheUpdated();
}
} // namespace net
......@@ -10,6 +10,7 @@
#include "base/time/time.h"
#include "base/values.h"
#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_observer.h"
#include "net/reporting/reporting_report.h"
#include "net/reporting/reporting_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -19,8 +20,28 @@
namespace net {
namespace {
class TestReportingObserver : public ReportingObserver {
public:
TestReportingObserver() : cache_update_count_(0) {}
void OnCacheUpdated() override { ++cache_update_count_; }
int cache_update_count() const { return cache_update_count_; }
private:
int cache_update_count_;
};
class ReportingCacheTest : public ReportingTestBase {
protected:
ReportingCacheTest() : ReportingTestBase() {
context()->AddObserver(&observer_);
}
~ReportingCacheTest() override { context()->RemoveObserver(&observer_); }
TestReportingObserver* observer() { return &observer_; }
const GURL kUrl1_ = GURL("https://origin1/path");
const url::Origin kOrigin1_ = url::Origin(GURL("https://origin1/"));
const url::Origin kOrigin2_ = url::Origin(GURL("https://origin2/"));
......@@ -32,6 +53,9 @@ class ReportingCacheTest : public ReportingTestBase {
const base::TimeTicks kNow_ = base::TimeTicks::Now();
const base::TimeTicks kExpires1_ = kNow_ + base::TimeDelta::FromDays(7);
const base::TimeTicks kExpires2_ = kExpires1_ + base::TimeDelta::FromDays(7);
private:
TestReportingObserver observer_;
};
TEST_F(ReportingCacheTest, Reports) {
......@@ -41,6 +65,7 @@ TEST_F(ReportingCacheTest, Reports) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
base::MakeUnique<base::DictionaryValue>(), kNow_, 0);
EXPECT_EQ(1, observer()->cache_update_count());
cache()->GetReports(&reports);
ASSERT_EQ(1u, reports.size());
......@@ -56,6 +81,7 @@ TEST_F(ReportingCacheTest, Reports) {
EXPECT_FALSE(cache()->IsReportDoomedForTesting(report));
cache()->IncrementReportsAttempts(reports);
EXPECT_EQ(2, observer()->cache_update_count());
cache()->GetReports(&reports);
ASSERT_EQ(1u, reports.size());
......@@ -64,6 +90,7 @@ TEST_F(ReportingCacheTest, Reports) {
EXPECT_EQ(1, report->attempts);
cache()->RemoveReports(reports);
EXPECT_EQ(3, observer()->cache_update_count());
cache()->GetReports(&reports);
EXPECT_TRUE(reports.empty());
......@@ -74,12 +101,14 @@ TEST_F(ReportingCacheTest, RemoveAllReports) {
base::MakeUnique<base::DictionaryValue>(), kNow_, 0);
cache()->AddReport(kUrl1_, kGroup1_, kType_,
base::MakeUnique<base::DictionaryValue>(), kNow_, 0);
EXPECT_EQ(2, observer()->cache_update_count());
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
EXPECT_EQ(2u, reports.size());
cache()->RemoveAllReports();
EXPECT_EQ(3, observer()->cache_update_count());
cache()->GetReports(&reports);
EXPECT_TRUE(reports.empty());
......@@ -88,6 +117,7 @@ TEST_F(ReportingCacheTest, RemoveAllReports) {
TEST_F(ReportingCacheTest, RemovePendingReports) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
base::MakeUnique<base::DictionaryValue>(), kNow_, 0);
EXPECT_EQ(1, observer()->cache_update_count());
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
......@@ -102,6 +132,7 @@ TEST_F(ReportingCacheTest, RemovePendingReports) {
cache()->RemoveReports(reports);
EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0]));
EXPECT_TRUE(cache()->IsReportDoomedForTesting(reports[0]));
EXPECT_EQ(2, observer()->cache_update_count());
// After removing report, future calls to GetReports should not return it.
std::vector<const ReportingReport*> visible_reports;
......@@ -117,6 +148,7 @@ TEST_F(ReportingCacheTest, RemovePendingReports) {
TEST_F(ReportingCacheTest, RemoveAllPendingReports) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
base::MakeUnique<base::DictionaryValue>(), kNow_, 0);
EXPECT_EQ(1, observer()->cache_update_count());
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
......@@ -131,6 +163,7 @@ TEST_F(ReportingCacheTest, RemoveAllPendingReports) {
cache()->RemoveAllReports();
EXPECT_TRUE(cache()->IsReportPendingForTesting(reports[0]));
EXPECT_TRUE(cache()->IsReportDoomedForTesting(reports[0]));
EXPECT_EQ(2, observer()->cache_update_count());
// After removing report, future calls to GetReports should not return it.
std::vector<const ReportingReport*> visible_reports;
......@@ -147,6 +180,7 @@ TEST_F(ReportingCacheTest, Endpoints) {
cache()->SetClient(kOrigin1_, kEndpoint1_,
ReportingClient::Subdomains::EXCLUDE, kGroup1_,
kExpires1_);
EXPECT_EQ(1, observer()->cache_update_count());
const ReportingClient* client =
FindClientInCache(cache(), kOrigin1_, kEndpoint1_);
......@@ -159,6 +193,7 @@ TEST_F(ReportingCacheTest, Endpoints) {
cache()->SetClient(kOrigin1_, kEndpoint1_,
ReportingClient::Subdomains::INCLUDE, kGroup2, kExpires2_);
EXPECT_EQ(2, observer()->cache_update_count());
client = FindClientInCache(cache(), kOrigin1_, kEndpoint1_);
ASSERT_TRUE(client);
......@@ -169,6 +204,7 @@ TEST_F(ReportingCacheTest, Endpoints) {
EXPECT_EQ(kExpires2_, client->expires);
cache()->RemoveClients(std::vector<const ReportingClient*>{client});
EXPECT_EQ(3, observer()->cache_update_count());
client = FindClientInCache(cache(), kOrigin1_, kEndpoint1_);
EXPECT_FALSE(client);
......@@ -202,8 +238,10 @@ TEST_F(ReportingCacheTest, RemoveClientForOriginAndEndpoint) {
cache()->SetClient(kOrigin2_, kEndpoint1_,
ReportingClient::Subdomains::EXCLUDE, kGroup1_,
kExpires1_);
EXPECT_EQ(3, observer()->cache_update_count());
cache()->RemoveClientForOriginAndEndpoint(kOrigin1_, kEndpoint1_);
EXPECT_EQ(4, observer()->cache_update_count());
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin1_, kGroup1_, &clients);
......@@ -225,8 +263,10 @@ TEST_F(ReportingCacheTest, RemoveClientsForEndpoint) {
cache()->SetClient(kOrigin2_, kEndpoint1_,
ReportingClient::Subdomains::EXCLUDE, kGroup1_,
kExpires1_);
EXPECT_EQ(3, observer()->cache_update_count());
cache()->RemoveClientsForEndpoint(kEndpoint1_);
EXPECT_EQ(4, observer()->cache_update_count());
std::vector<const ReportingClient*> clients;
cache()->GetClientsForOriginAndGroup(kOrigin1_, kGroup1_, &clients);
......@@ -246,8 +286,10 @@ TEST_F(ReportingCacheTest, RemoveAllClients) {
cache()->SetClient(kOrigin2_, kEndpoint2_,
ReportingClient::Subdomains::EXCLUDE, kGroup1_,
kExpires1_);
EXPECT_EQ(2, observer()->cache_update_count());
cache()->RemoveAllClients();
EXPECT_EQ(3, observer()->cache_update_count());
std::vector<const ReportingClient*> clients;
cache()->GetClients(&clients);
......
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/memory/ptr_util.h"
#include "base/observer_list.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "base/time/default_tick_clock.h"
......@@ -17,6 +18,7 @@
#include "net/reporting/reporting_delegate.h"
#include "net/reporting/reporting_delivery_agent.h"
#include "net/reporting/reporting_endpoint_manager.h"
#include "net/reporting/reporting_observer.h"
#include "net/reporting/reporting_policy.h"
namespace net {
......@@ -50,6 +52,21 @@ std::unique_ptr<ReportingContext> ReportingContext::Create(
ReportingContext::~ReportingContext() {}
void ReportingContext::AddObserver(ReportingObserver* observer) {
DCHECK(!observers_.HasObserver(observer));
observers_.AddObserver(observer);
}
void ReportingContext::RemoveObserver(ReportingObserver* observer) {
DCHECK(observers_.HasObserver(observer));
observers_.RemoveObserver(observer);
}
void ReportingContext::NotifyCacheUpdated() {
for (auto& observer : observers_)
observer.OnCacheUpdated();
}
ReportingContext::ReportingContext(const ReportingPolicy& policy,
std::unique_ptr<ReportingDelegate> delegate,
std::unique_ptr<base::Clock> clock,
......
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/observer_list.h"
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
#include "net/base/net_export.h"
......@@ -23,6 +24,7 @@ class ReportingCache;
class ReportingDelegate;
class ReportingDeliveryAgent;
class ReportingEndpointManager;
class ReportingObserver;
class ReportingUploader;
class URLRequestContext;
......@@ -50,6 +52,11 @@ class NET_EXPORT ReportingContext {
}
ReportingDeliveryAgent* delivery_agent() { return delivery_agent_.get(); }
void AddObserver(ReportingObserver* observer);
void RemoveObserver(ReportingObserver* observer);
void NotifyCacheUpdated();
protected:
ReportingContext(const ReportingPolicy& policy,
std::unique_ptr<ReportingDelegate> delegate,
......@@ -65,6 +72,8 @@ class NET_EXPORT ReportingContext {
std::unique_ptr<base::TickClock> tick_clock_;
std::unique_ptr<ReportingUploader> uploader_;
base::ObserverList<ReportingObserver, /* check_empty= */ true> observers_;
std::unique_ptr<ReportingCache> cache_;
// |endpoint_manager_| must come after |tick_clock_| and |cache_|.
......
// Copyright 2017 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 "net/reporting/reporting_observer.h"
namespace net {
void ReportingObserver::OnCacheUpdated() {}
ReportingObserver::ReportingObserver() {}
ReportingObserver::~ReportingObserver() {}
} // namespace net
// Copyright 2017 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 NET_REPORTING_REPORTING_OBSERVER_H_
#define NET_REPORTING_REPORTING_OBSERVER_H_
#include "base/macros.h"
#include "net/base/net_export.h"
namespace net {
class NET_EXPORT ReportingObserver {
public:
virtual void OnCacheUpdated();
protected:
ReportingObserver();
~ReportingObserver();
DISALLOW_COPY_AND_ASSIGN(ReportingObserver);
};
} // namespace net
#endif // NET_REPORTING_REPORTING_OBSERVER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment