Commit af37afb4 authored by Eric Robinson's avatar Eric Robinson Committed by Commit Bot

Split out .cc classes for RulesetService.

See also go/chromerulesetservicemerge.

This change is the final step in the RulesetService change.
Rather than merging the two classes, we've chosen to more
appropriately name ContentRulesetService to reflect what it
does (RulesetPublisherImpl).  In addition, the visibility of that
class has been reduced, and it is now only referenced in/visible
to the RulesetService class as well as tests.

This change reflects splitting up the content of the .cc files,
as the splitting of the headers was done in a previous CL.

Change-Id: I2937ba2e2838669d3bf6a2f646acfefcd71f5f94
Reviewed-on: https://chromium-review.googlesource.com/c/1354272
Commit-Queue: Eric Robinson <ericrobinson@chromium.org>
Reviewed-by: default avatarCharlie Harrison <csharrison@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612695}
parent 3546854f
......@@ -17,9 +17,12 @@ static_library("browser") {
"page_load_statistics.cc",
"page_load_statistics.h",
"ruleset_publisher.h",
"ruleset_publisher_impl.cc",
"ruleset_publisher_impl.h",
"ruleset_service.cc",
"ruleset_service.h",
"ruleset_version.cc",
"ruleset_version.h",
"subframe_navigation_filtering_throttle.cc",
"subframe_navigation_filtering_throttle.h",
"subresource_filter_client.h",
......@@ -88,6 +91,7 @@ source_set("unit_tests") {
"content_activation_list_utils_unittest.cc",
"content_subresource_filter_throttle_manager_unittest.cc",
"navigation_console_logger_unittest.cc",
"ruleset_publisher_impl_unittest.cc",
"ruleset_service_unittest.cc",
"subframe_navigation_filtering_throttle_unittest.cc",
"subresource_filter_safe_browsing_activation_throttle_unittest.cc",
......
......@@ -5,9 +5,6 @@
#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_RULESET_PUBLISHER_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_RULESET_PUBLISHER_H_
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
......@@ -15,71 +12,8 @@
#include "base/single_thread_task_runner.h"
#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
class PrefRegistrySimple;
class PrefService;
namespace base {
namespace trace_event {
class TracedValue;
} // namespace trace_event
} // namespace base
namespace subresource_filter {
// Encapsulates information about a version of unindexed subresource
// filtering rules on disk.
struct UnindexedRulesetInfo {
UnindexedRulesetInfo();
~UnindexedRulesetInfo();
// The version of the ruleset contents. Because the wire format of unindexed
// rules is expected to be stable over time (at least backwards compatible),
// the unindexed ruleset is uniquely identified by its content version.
//
// The version string must not be empty, but can be any string otherwise.
// There is no ordering defined on versions.
std::string content_version;
// The path to the file containing the unindexed subresource filtering rules.
base::FilePath ruleset_path;
// The (optional) path to a file containing the applicable license, which will
// be copied next to the indexed ruleset. For convenience, the lack of license
// can be indicated not only by setting |license_path| to empty, but also by
// setting it to any non existent path.
base::FilePath license_path;
};
// Encapsulates the combination of the binary format version of the indexed
// ruleset, and the version of the ruleset contents.
//
// In contrast to the unindexed ruleset, the binary format of the index data
// structures is expected to evolve over time, so the indexed ruleset is
// identified by a pair of versions: the content version of the rules that have
// been indexed; and the binary format version of the indexed data structures.
// It also contains a checksum of the data, to ensure it hasn't been corrupted.
struct IndexedRulesetVersion {
IndexedRulesetVersion();
IndexedRulesetVersion(const std::string& content_version, int format_version);
~IndexedRulesetVersion();
IndexedRulesetVersion& operator=(const IndexedRulesetVersion&);
static void RegisterPrefs(PrefRegistrySimple* registry);
static int CurrentFormatVersion();
bool IsValid() const;
bool IsCurrentFormatVersion() const;
void SaveToPrefs(PrefService* local_state) const;
void ReadFromPrefs(PrefService* local_state);
std::unique_ptr<base::trace_event::TracedValue> ToTracedValue() const;
std::string content_version;
int format_version = 0;
int checksum = 0;
};
// Interface for a RulesetService that defines operations that distribute the
// ruleset to the renderer processes via the RulesetDealer.
class RulesetPublisher {
......
// Copyright 2018 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 "components/subresource_filter/content/browser/ruleset_publisher_impl.h"
#include <utility>
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "components/subresource_filter/content/common/subresource_filter_messages.h"
#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
#include "components/subresource_filter/core/common/common_features.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "ipc/ipc_platform_file.h"
namespace subresource_filter {
namespace {
void SendRulesetToRenderProcess(base::File* file,
content::RenderProcessHost* rph) {
DCHECK(rph);
DCHECK(file);
DCHECK(file->IsValid());
rph->Send(new SubresourceFilterMsg_SetRulesetForProcess(
IPC::TakePlatformFileForTransit(file->Duplicate())));
}
// The file handle is closed when the argument goes out of scope.
void CloseFile(base::File) {}
// Posts the |file| handle to the file thread so it can be closed.
void CloseFileOnFileThread(base::File* file) {
if (!file->IsValid())
return;
base::PostTaskWithTraits(FROM_HERE,
{base::TaskPriority::BEST_EFFORT, base::MayBlock()},
base::BindOnce(&CloseFile, std::move(*file)));
}
} // namespace
RulesetPublisherImpl::RulesetPublisherImpl(
RulesetService* ruleset_service,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
: ruleset_service_(ruleset_service),
ruleset_dealer_(std::make_unique<VerifiedRulesetDealer::Handle>(
std::move(blocking_task_runner))) {
best_effort_task_runner_ = base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT});
DCHECK(best_effort_task_runner_->BelongsToCurrentThread());
// Must rely on notifications as RenderProcessHostObserver::RenderProcessReady
// would only be called after queued IPC messages (potentially triggering a
// navigation) had already been sent to the new renderer.
notification_registrar_.Add(
this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
content::NotificationService::AllBrowserContextsAndSources());
}
RulesetPublisherImpl::~RulesetPublisherImpl() {
CloseFileOnFileThread(&ruleset_data_);
}
void RulesetPublisherImpl::SetRulesetPublishedCallbackForTesting(
base::OnceClosure callback) {
ruleset_published_callback_ = std::move(callback);
}
void RulesetPublisherImpl::TryOpenAndSetRulesetFile(
const base::FilePath& file_path,
int expected_checksum,
base::OnceCallback<void(base::File)> callback) {
GetRulesetDealer()->TryOpenAndSetRulesetFile(file_path, expected_checksum,
std::move(callback));
}
void RulesetPublisherImpl::PublishNewRulesetVersion(base::File ruleset_data) {
DCHECK(ruleset_data.IsValid());
CloseFileOnFileThread(&ruleset_data_);
// If Ad Tagging is running, then every request does a lookup and it's
// important that we verify the ruleset early on.
if (base::FeatureList::IsEnabled(kAdTagging)) {
// Even though the handle will immediately be destroyed, it will still
// validate the ruleset on its task runner.
VerifiedRuleset::Handle ruleset_handle(GetRulesetDealer());
}
ruleset_data_ = std::move(ruleset_data);
for (auto it = content::RenderProcessHost::AllHostsIterator(); !it.IsAtEnd();
it.Advance()) {
SendRulesetToRenderProcess(&ruleset_data_, it.GetCurrentValue());
}
if (!ruleset_published_callback_.is_null())
std::move(ruleset_published_callback_).Run();
}
scoped_refptr<base::SingleThreadTaskRunner>
RulesetPublisherImpl::BestEffortTaskRunner() {
return best_effort_task_runner_;
}
VerifiedRulesetDealer::Handle* RulesetPublisherImpl::GetRulesetDealer() {
return ruleset_dealer_.get();
}
void RulesetPublisherImpl::IndexAndStoreAndPublishRulesetIfNeeded(
const UnindexedRulesetInfo& unindexed_ruleset_info) {
DCHECK(ruleset_service_);
ruleset_service_->IndexAndStoreAndPublishRulesetIfNeeded(
unindexed_ruleset_info);
}
void RulesetPublisherImpl::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_CREATED);
if (!ruleset_data_.IsValid())
return;
SendRulesetToRenderProcess(
&ruleset_data_,
content::Source<content::RenderProcessHost>(source).ptr());
}
} // namespace subresource_filter
......@@ -14,6 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "components/subresource_filter/content/browser/ruleset_publisher.h"
#include "components/subresource_filter/content/browser/ruleset_version.h"
#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
......
// Copyright 2018 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 "components/subresource_filter/content/browser/ruleset_publisher_impl.h"
#include <stddef.h>
#include <string>
#include <tuple>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/numerics/safe_conversions.h"
#include "base/run_loop.h"
#include "base/task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/prefs/testing_pref_service.h"
#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "components/subresource_filter/content/common/subresource_filter_messages.h"
#include "components/subresource_filter/core/common/test_ruleset_creator.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "ipc/ipc_platform_file.h"
#include "ipc/ipc_test_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace subresource_filter {
namespace {
using MockClosureTarget =
::testing::StrictMock<::testing::MockFunction<void()>>;
class NotifyingMockRenderProcessHost : public content::MockRenderProcessHost {
public:
explicit NotifyingMockRenderProcessHost(
content::BrowserContext* browser_context)
: content::MockRenderProcessHost(browser_context) {
content::NotificationService::current()->Notify(
content::NOTIFICATION_RENDERER_PROCESS_CREATED,
content::Source<content::RenderProcessHost>(this),
content::NotificationService::NoDetails());
}
};
std::string ReadFileContentsToString(base::File* file) {
size_t length = base::checked_cast<size_t>(file->GetLength());
std::string contents(length, 0);
file->Read(0, &contents[0], base::checked_cast<int>(length));
return contents;
}
// Extracts and takes ownership of the ruleset file handle in the IPC message.
base::File ExtractRulesetFromMessage(const IPC::Message* message) {
std::tuple<IPC::PlatformFileForTransit> arg;
SubresourceFilterMsg_SetRulesetForProcess::Read(message, &arg);
return IPC::PlatformFileForTransitToFile(std::get<0>(arg));
}
} // namespace
class SubresourceFilterRulesetPublisherImplTest : public ::testing::Test {
public:
SubresourceFilterRulesetPublisherImplTest()
: existing_renderer_(&browser_context_) {}
protected:
void SetUp() override { ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); }
void TearDown() override {}
content::TestBrowserContext* browser_context() { return &browser_context_; }
base::FilePath scoped_temp_file() const {
return scoped_temp_dir_.GetPath().AppendASCII("data");
}
void AssertSetRulesetForProcessMessageWithContent(
const IPC::Message* message,
const std::string& expected_contents) {
ASSERT_EQ(
static_cast<uint32_t>(SubresourceFilterMsg_SetRulesetForProcess::ID),
message->type());
base::File ruleset_file = ExtractRulesetFromMessage(message);
ASSERT_TRUE(ruleset_file.IsValid());
ASSERT_EQ(expected_contents, ReadFileContentsToString(&ruleset_file));
}
private:
base::ScopedTempDir scoped_temp_dir_;
content::TestBrowserThreadBundle thread_bundle_;
content::TestBrowserContext browser_context_;
NotifyingMockRenderProcessHost existing_renderer_;
DISALLOW_COPY_AND_ASSIGN(SubresourceFilterRulesetPublisherImplTest);
};
TEST_F(SubresourceFilterRulesetPublisherImplTest, NoRuleset_NoIPCMessages) {
NotifyingMockRenderProcessHost existing_renderer(browser_context());
RulesetPublisherImpl service(nullptr, base::ThreadTaskRunnerHandle::Get());
NotifyingMockRenderProcessHost new_renderer(browser_context());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0u, existing_renderer.sink().message_count());
EXPECT_EQ(0u, new_renderer.sink().message_count());
}
TEST_F(SubresourceFilterRulesetPublisherImplTest,
PublishedRuleset_IsDistributedToExistingAndNewRenderers) {
const char kTestFileContents[] = "foobar";
base::WriteFile(scoped_temp_file(), kTestFileContents,
strlen(kTestFileContents));
base::File file;
file.Initialize(scoped_temp_file(),
base::File::FLAG_OPEN | base::File::FLAG_READ);
NotifyingMockRenderProcessHost existing_renderer(browser_context());
MockClosureTarget publish_callback_target;
RulesetPublisherImpl service(nullptr, base::ThreadTaskRunnerHandle::Get());
service.SetRulesetPublishedCallbackForTesting(base::BindOnce(
&MockClosureTarget::Call, base::Unretained(&publish_callback_target)));
EXPECT_CALL(publish_callback_target, Call()).Times(1);
service.PublishNewRulesetVersion(std::move(file));
base::RunLoop().RunUntilIdle();
::testing::Mock::VerifyAndClearExpectations(&publish_callback_target);
ASSERT_EQ(1u, existing_renderer.sink().message_count());
ASSERT_NO_FATAL_FAILURE(AssertSetRulesetForProcessMessageWithContent(
existing_renderer.sink().GetMessageAt(0), kTestFileContents));
NotifyingMockRenderProcessHost second_renderer(browser_context());
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1u, second_renderer.sink().message_count());
ASSERT_NO_FATAL_FAILURE(AssertSetRulesetForProcessMessageWithContent(
second_renderer.sink().GetMessageAt(0), kTestFileContents));
}
TEST_F(SubresourceFilterRulesetPublisherImplTest,
PublishesRulesetInOnePostTask) {
// Regression test for crbug.com/817308. Test verifies that ruleset is
// published on browser startup via exactly one PostTask.
// Create a temporary directory for the indexed ruleset data.
base::ScopedTempDir scoped_temp_dir;
ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
const base::FilePath base_dir =
scoped_temp_dir.GetPath().AppendASCII("Rules").AppendASCII("Indexed");
// Create a testing ruleset.
testing::TestRulesetPair ruleset;
ASSERT_NO_FATAL_FAILURE(
testing::TestRulesetCreator().CreateRulesetToDisallowURLsWithPathSuffix(
"foo", &ruleset));
// Create local state and save the ruleset version to emulate invariant that
// the version of the last indexed ruleset is stored in the local state.
TestingPrefServiceSimple prefs;
IndexedRulesetVersion::RegisterPrefs(prefs.registry());
IndexedRulesetVersion current_version(
"1.2.3.4", IndexedRulesetVersion::CurrentFormatVersion());
current_version.SaveToPrefs(&prefs);
// Create ruleset data on a disk.
const base::FilePath version_dir_path =
IndexedRulesetLocator::GetSubdirectoryPathForVersion(base_dir,
current_version);
ASSERT_EQ(RulesetService::IndexAndWriteRulesetResult::SUCCESS,
RulesetService::WriteRuleset(version_dir_path,
/* license_path =*/base::FilePath(),
ruleset.indexed.contents.data(),
ruleset.indexed.contents.size()));
// Create a ruleset service and its harness.
scoped_refptr<base::TestSimpleTaskRunner> blocking_task_runner =
base::MakeRefCounted<base::TestSimpleTaskRunner>();
scoped_refptr<base::TestSimpleTaskRunner> background_task_runner =
base::MakeRefCounted<base::TestSimpleTaskRunner>();
NotifyingMockRenderProcessHost renderer_host(browser_context());
base::RunLoop callback_waiter;
auto content_service =
std::make_unique<RulesetPublisherImpl>(nullptr, blocking_task_runner);
content_service->SetRulesetPublishedCallbackForTesting(
callback_waiter.QuitClosure());
// |RulesetService| constructor should read the last indexed ruleset version
// and post ruleset setup on |blocking_task_runner|.
ASSERT_EQ(0u, blocking_task_runner->NumPendingTasks());
auto service =
std::make_unique<RulesetService>(&prefs, background_task_runner, base_dir,
nullptr, std::move(content_service));
// The key test assertion is that ruleset data is published via exactly one
// post task on |blocking_task_runner|. It is important to run pending tasks
// only once here.
ASSERT_EQ(1u, blocking_task_runner->NumPendingTasks());
blocking_task_runner->RunPendingTasks();
callback_waiter.Run();
// Check that the ruleset data is delivered to the renderer.
EXPECT_EQ(1u, renderer_host.sink().message_count());
const std::string expected_data(ruleset.indexed.contents.begin(),
ruleset.indexed.contents.end());
ASSERT_NO_FATAL_FAILURE(AssertSetRulesetForProcessMessageWithContent(
renderer_host.sink().GetMessageAt(0), expected_data));
//
// |RulesetPublisherImpl| destruction requires additional tricks. Its member
// |VerifiedRulesetDealer::Handle| posts task upon destruction on
// |blocking_task_runner|.
service.reset();
// Need to wait for |VerifiedRulesetDealer| destruction on the
// |blocking_task_runner|.
blocking_task_runner->RunPendingTasks();
}
} // namespace subresource_filter
......@@ -3,12 +3,10 @@
// found in the LICENSE file.
#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "components/subresource_filter/content/browser/ruleset_publisher_impl.h"
#include <utility>
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
......@@ -17,7 +15,6 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/rand_util.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
......@@ -27,6 +24,8 @@
#include "base/trace_event/traced_value.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/subresource_filter/content/browser/ruleset_publisher.h"
#include "components/subresource_filter/content/browser/ruleset_publisher_impl.h"
#include "components/subresource_filter/content/common/subresource_filter_messages.h"
#include "components/subresource_filter/core/browser/copying_file_stream.h"
#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
......@@ -37,28 +36,13 @@
#include "components/url_pattern_index/proto/rules.pb.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "ipc/ipc_platform_file.h"
#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
namespace subresource_filter {
// Constant definitions and helper functions ---------------------------------
namespace {
// Names of the preferences storing the most recent ruleset version that
// was successfully stored to disk.
const char kSubresourceFilterRulesetContentVersion[] =
"subresource_filter.ruleset_version.content";
const char kSubresourceFilterRulesetFormatVersion[] =
"subresource_filter.ruleset_version.format";
const char kSubresourceFilterRulesetChecksum[] =
"subresource_filter.ruleset_version.checksum";
void RecordIndexAndWriteRulesetResult(
RulesetService::IndexAndWriteRulesetResult result) {
UMA_HISTOGRAM_ENUMERATION(
......@@ -100,89 +84,8 @@ class SentinelFile {
DISALLOW_COPY_AND_ASSIGN(SentinelFile);
};
void SendRulesetToRenderProcess(base::File* file,
content::RenderProcessHost* rph) {
DCHECK(rph);
DCHECK(file);
DCHECK(file->IsValid());
rph->Send(new SubresourceFilterMsg_SetRulesetForProcess(
IPC::TakePlatformFileForTransit(file->Duplicate())));
}
// The file handle is closed when the argument goes out of scope.
void CloseFile(base::File) {}
// Posts the |file| handle to the file thread so it can be closed.
void CloseFileOnFileThread(base::File* file) {
if (!file->IsValid())
return;
base::PostTaskWithTraits(FROM_HERE,
{base::TaskPriority::BEST_EFFORT, base::MayBlock()},
base::BindOnce(&CloseFile, std::move(*file)));
}
} // namespace
// UnindexedRulesetInfo -------------------------------------------------------
UnindexedRulesetInfo::UnindexedRulesetInfo() = default;
UnindexedRulesetInfo::~UnindexedRulesetInfo() = default;
// IndexedRulesetVersion ------------------------------------------------------
IndexedRulesetVersion::IndexedRulesetVersion() = default;
IndexedRulesetVersion::IndexedRulesetVersion(const std::string& content_version,
int format_version)
: content_version(content_version), format_version(format_version) {}
IndexedRulesetVersion::~IndexedRulesetVersion() = default;
IndexedRulesetVersion& IndexedRulesetVersion::operator=(
const IndexedRulesetVersion&) = default;
// static
void IndexedRulesetVersion::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterStringPref(kSubresourceFilterRulesetContentVersion,
std::string());
registry->RegisterIntegerPref(kSubresourceFilterRulesetFormatVersion, 0);
registry->RegisterIntegerPref(kSubresourceFilterRulesetChecksum, 0);
}
// static
int IndexedRulesetVersion::CurrentFormatVersion() {
return RulesetIndexer::kIndexedFormatVersion;
}
void IndexedRulesetVersion::ReadFromPrefs(PrefService* local_state) {
format_version =
local_state->GetInteger(kSubresourceFilterRulesetFormatVersion);
content_version =
local_state->GetString(kSubresourceFilterRulesetContentVersion);
checksum = local_state->GetInteger(kSubresourceFilterRulesetChecksum);
}
bool IndexedRulesetVersion::IsValid() const {
return format_version != 0 && !content_version.empty();
}
bool IndexedRulesetVersion::IsCurrentFormatVersion() const {
return format_version == CurrentFormatVersion();
}
void IndexedRulesetVersion::SaveToPrefs(PrefService* local_state) const {
local_state->SetInteger(kSubresourceFilterRulesetFormatVersion,
format_version);
local_state->SetString(kSubresourceFilterRulesetContentVersion,
content_version);
local_state->SetInteger(kSubresourceFilterRulesetChecksum, checksum);
}
std::unique_ptr<base::trace_event::TracedValue>
IndexedRulesetVersion::ToTracedValue() const {
auto value = std::make_unique<base::trace_event::TracedValue>();
value->SetString("content_version", content_version);
value->SetInteger("format_version", format_version);
return value;
}
// IndexedRulesetLocator ------------------------------------------------------
// static
......@@ -551,90 +454,4 @@ void RulesetService::OnRulesetSet(base::File file) {
publisher_->PublishNewRulesetVersion(std::move(file));
}
// RulesetPublisherImpl ------------------------------------------------------
RulesetPublisherImpl::RulesetPublisherImpl(
RulesetService* ruleset_service,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
: ruleset_service_(ruleset_service),
ruleset_dealer_(std::make_unique<VerifiedRulesetDealer::Handle>(
std::move(blocking_task_runner))) {
best_effort_task_runner_ = base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT});
DCHECK(best_effort_task_runner_->BelongsToCurrentThread());
// Must rely on notifications as RenderProcessHostObserver::RenderProcessReady
// would only be called after queued IPC messages (potentially triggering a
// navigation) had already been sent to the new renderer.
notification_registrar_.Add(
this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
content::NotificationService::AllBrowserContextsAndSources());
}
RulesetPublisherImpl::~RulesetPublisherImpl() {
CloseFileOnFileThread(&ruleset_data_);
}
void RulesetPublisherImpl::SetRulesetPublishedCallbackForTesting(
base::OnceClosure callback) {
ruleset_published_callback_ = std::move(callback);
}
void RulesetPublisherImpl::TryOpenAndSetRulesetFile(
const base::FilePath& file_path,
int expected_checksum,
base::OnceCallback<void(base::File)> callback) {
GetRulesetDealer()->TryOpenAndSetRulesetFile(file_path, expected_checksum,
std::move(callback));
}
void RulesetPublisherImpl::PublishNewRulesetVersion(base::File ruleset_data) {
DCHECK(ruleset_data.IsValid());
CloseFileOnFileThread(&ruleset_data_);
// If Ad Tagging is running, then every request does a lookup and it's
// important that we verify the ruleset early on.
if (base::FeatureList::IsEnabled(kAdTagging)) {
// Even though the handle will immediately be destroyed, it will still
// validate the ruleset on its task runner.
VerifiedRuleset::Handle ruleset_handle(GetRulesetDealer());
}
ruleset_data_ = std::move(ruleset_data);
for (auto it = content::RenderProcessHost::AllHostsIterator(); !it.IsAtEnd();
it.Advance()) {
SendRulesetToRenderProcess(&ruleset_data_, it.GetCurrentValue());
}
if (!ruleset_published_callback_.is_null())
std::move(ruleset_published_callback_).Run();
}
scoped_refptr<base::SingleThreadTaskRunner>
RulesetPublisherImpl::BestEffortTaskRunner() {
return best_effort_task_runner_;
}
VerifiedRulesetDealer::Handle* RulesetPublisherImpl::GetRulesetDealer() {
return ruleset_dealer_.get();
}
void RulesetPublisherImpl::IndexAndStoreAndPublishRulesetIfNeeded(
const UnindexedRulesetInfo& unindexed_ruleset_info) {
DCHECK(ruleset_service_);
ruleset_service_->IndexAndStoreAndPublishRulesetIfNeeded(
unindexed_ruleset_info);
}
void RulesetPublisherImpl::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_CREATED);
if (!ruleset_data_.IsValid())
return;
SendRulesetToRenderProcess(
&ruleset_data_,
content::Source<content::RenderProcessHost>(source).ptr());
}
} // namespace subresource_filter
......@@ -47,6 +47,7 @@
#include "base/single_thread_task_runner.h"
#include "base/version.h"
#include "components/subresource_filter/content/browser/ruleset_publisher.h"
#include "components/subresource_filter/content/browser/ruleset_version.h"
#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
......
// Copyright 2018 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 "components/subresource_filter/content/browser/ruleset_version.h"
#include "base/trace_event/traced_value.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/subresource_filter/core/common/indexed_ruleset.h"
namespace subresource_filter {
namespace {
// Names of the preferences storing the most recent ruleset version that
// was successfully stored to disk.
const char kSubresourceFilterRulesetContentVersion[] =
"subresource_filter.ruleset_version.content";
const char kSubresourceFilterRulesetFormatVersion[] =
"subresource_filter.ruleset_version.format";
const char kSubresourceFilterRulesetChecksum[] =
"subresource_filter.ruleset_version.checksum";
} // namespace
UnindexedRulesetInfo::UnindexedRulesetInfo() = default;
UnindexedRulesetInfo::~UnindexedRulesetInfo() = default;
IndexedRulesetVersion::IndexedRulesetVersion() = default;
IndexedRulesetVersion::IndexedRulesetVersion(const std::string& content_version,
int format_version)
: content_version(content_version), format_version(format_version) {}
IndexedRulesetVersion::~IndexedRulesetVersion() = default;
IndexedRulesetVersion& IndexedRulesetVersion::operator=(
const IndexedRulesetVersion&) = default;
// static
void IndexedRulesetVersion::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterStringPref(kSubresourceFilterRulesetContentVersion,
std::string());
registry->RegisterIntegerPref(kSubresourceFilterRulesetFormatVersion, 0);
registry->RegisterIntegerPref(kSubresourceFilterRulesetChecksum, 0);
}
// static
int IndexedRulesetVersion::CurrentFormatVersion() {
return RulesetIndexer::kIndexedFormatVersion;
}
void IndexedRulesetVersion::ReadFromPrefs(PrefService* local_state) {
format_version =
local_state->GetInteger(kSubresourceFilterRulesetFormatVersion);
content_version =
local_state->GetString(kSubresourceFilterRulesetContentVersion);
checksum = local_state->GetInteger(kSubresourceFilterRulesetChecksum);
}
bool IndexedRulesetVersion::IsValid() const {
return format_version != 0 && !content_version.empty();
}
bool IndexedRulesetVersion::IsCurrentFormatVersion() const {
return format_version == CurrentFormatVersion();
}
void IndexedRulesetVersion::SaveToPrefs(PrefService* local_state) const {
local_state->SetInteger(kSubresourceFilterRulesetFormatVersion,
format_version);
local_state->SetString(kSubresourceFilterRulesetContentVersion,
content_version);
local_state->SetInteger(kSubresourceFilterRulesetChecksum, checksum);
}
std::unique_ptr<base::trace_event::TracedValue>
IndexedRulesetVersion::ToTracedValue() const {
auto value = std::make_unique<base::trace_event::TracedValue>();
value->SetString("content_version", content_version);
value->SetInteger("format_version", format_version);
return value;
}
} // namespace subresource_filter
// Copyright 2018 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 COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_RULESET_VERSION_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_RULESET_VERSION_H_
#include <memory>
#include <string>
#include "base/files/file_path.h"
class PrefRegistrySimple;
class PrefService;
namespace base {
namespace trace_event {
class TracedValue;
} // namespace trace_event
} // namespace base
namespace subresource_filter {
// Encapsulates information about a version of unindexed subresource
// filtering rules on disk.
struct UnindexedRulesetInfo {
UnindexedRulesetInfo();
~UnindexedRulesetInfo();
// The version of the ruleset contents. Because the wire format of unindexed
// rules is expected to be stable over time (at least backwards compatible),
// the unindexed ruleset is uniquely identified by its content version.
//
// The version string must not be empty, but can be any string otherwise.
// There is no ordering defined on versions.
std::string content_version;
// The path to the file containing the unindexed subresource filtering rules.
base::FilePath ruleset_path;
// The (optional) path to a file containing the applicable license, which will
// be copied next to the indexed ruleset. For convenience, the lack of license
// can be indicated not only by setting |license_path| to empty, but also by
// setting it to any non existent path.
base::FilePath license_path;
};
// Encapsulates the combination of the binary format version of the indexed
// ruleset, and the version of the ruleset contents.
//
// In contrast to the unindexed ruleset, the binary format of the index data
// structures is expected to evolve over time, so the indexed ruleset is
// identified by a pair of versions: the content version of the rules that have
// been indexed; and the binary format version of the indexed data structures.
// It also contains a checksum of the data, to ensure it hasn't been corrupted.
struct IndexedRulesetVersion {
IndexedRulesetVersion();
IndexedRulesetVersion(const std::string& content_version, int format_version);
~IndexedRulesetVersion();
IndexedRulesetVersion& operator=(const IndexedRulesetVersion&);
static void RegisterPrefs(PrefRegistrySimple* registry);
static int CurrentFormatVersion();
bool IsValid() const;
bool IsCurrentFormatVersion() const;
void SaveToPrefs(PrefService* local_state) const;
void ReadFromPrefs(PrefService* local_state);
std::unique_ptr<base::trace_event::TracedValue> ToTracedValue() const;
std::string content_version;
int format_version = 0;
int checksum = 0;
};
} // namespace subresource_filter
#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_RULESET_VERSION_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