[perf] Share adblock resource storage to save memory (Desktop & Android) (#32562)
The PR enables adblock resource sharing between the default and the additional engine to save memory. It also replaces text based resource merging AdBlockCustomResourceProvider to .add_resource(..) calls.
This commit is contained in:
@@ -162,12 +162,10 @@ void AdBlockEngine::EnableTag(const std::string& tag, bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
void AdBlockEngine::UseResources(const std::string& resources) {
|
||||
void AdBlockEngine::UseResources(
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
bool result = ad_block_client_->use_resources(resources);
|
||||
if (!result) {
|
||||
LOG(ERROR) << "AdBlockEngine::UseResources failed";
|
||||
}
|
||||
ad_block_client_->use_resource_storage(storage);
|
||||
}
|
||||
|
||||
bool AdBlockEngine::TagExists(const std::string& tag) {
|
||||
@@ -244,23 +242,23 @@ base::Value::List AdBlockEngine::HiddenClassIdSelectors(
|
||||
|
||||
void AdBlockEngine::Load(bool deserialize,
|
||||
const DATFileDataBuffer& dat_buf,
|
||||
const std::string& resources_json) {
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
if (deserialize) {
|
||||
OnDATLoaded(dat_buf, resources_json);
|
||||
OnDATLoaded(dat_buf, storage);
|
||||
} else {
|
||||
OnListSourceLoaded(dat_buf, resources_json);
|
||||
OnListSourceLoaded(dat_buf, storage);
|
||||
}
|
||||
}
|
||||
|
||||
void AdBlockEngine::Load(rust::Box<adblock::FilterSet> filter_set,
|
||||
const std::string& resources_json) {
|
||||
OnFilterSetLoaded(std::move(filter_set), resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
OnFilterSetLoaded(std::move(filter_set), storage);
|
||||
}
|
||||
|
||||
void AdBlockEngine::UpdateAdBlockClient(
|
||||
rust::Box<adblock::Engine> ad_block_client,
|
||||
const std::string& resources_json) {
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
TRACE_EVENT("brave.adblock", "UpdateAdBlockClient");
|
||||
@@ -268,7 +266,7 @@ void AdBlockEngine::UpdateAdBlockClient(
|
||||
if (regex_discard_policy_) {
|
||||
ad_block_client_->set_regex_discard_policy(*regex_discard_policy_);
|
||||
}
|
||||
UseResources(resources_json);
|
||||
UseResources(storage);
|
||||
AddKnownTagsToAdBlockInstance();
|
||||
if (test_observer_) {
|
||||
test_observer_->OnEngineUpdated();
|
||||
@@ -283,8 +281,9 @@ void AdBlockEngine::AddKnownTagsToAdBlockInstance() {
|
||||
});
|
||||
}
|
||||
|
||||
void AdBlockEngine::OnFilterSetLoaded(rust::Box<adblock::FilterSet> filter_set,
|
||||
const std::string& resources_json) {
|
||||
void AdBlockEngine::OnFilterSetLoaded(
|
||||
rust::Box<adblock::FilterSet> filter_set,
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
base::ElapsedTimer timer;
|
||||
@@ -307,11 +306,12 @@ void AdBlockEngine::OnFilterSetLoaded(rust::Box<adblock::FilterSet> filter_set,
|
||||
<< result.error_message.c_str();
|
||||
return;
|
||||
}
|
||||
UpdateAdBlockClient(std::move(result.value), resources_json);
|
||||
UpdateAdBlockClient(std::move(result.value), storage);
|
||||
}
|
||||
|
||||
void AdBlockEngine::OnListSourceLoaded(const DATFileDataBuffer& filters,
|
||||
const std::string& resources_json) {
|
||||
void AdBlockEngine::OnListSourceLoaded(
|
||||
const DATFileDataBuffer& filters,
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
base::ElapsedTimer timer;
|
||||
@@ -334,11 +334,12 @@ void AdBlockEngine::OnListSourceLoaded(const DATFileDataBuffer& filters,
|
||||
<< result.error_message.c_str();
|
||||
return;
|
||||
}
|
||||
UpdateAdBlockClient(std::move(result.value), resources_json);
|
||||
UpdateAdBlockClient(std::move(result.value), storage);
|
||||
}
|
||||
|
||||
void AdBlockEngine::OnDATLoaded(const DATFileDataBuffer& dat_buf,
|
||||
const std::string& resources_json) {
|
||||
void AdBlockEngine::OnDATLoaded(
|
||||
const DATFileDataBuffer& dat_buf,
|
||||
const adblock::BraveCoreResourceStorage& storage) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
// An empty buffer will not load successfully.
|
||||
@@ -367,7 +368,7 @@ void AdBlockEngine::OnDATLoaded(const DATFileDataBuffer& dat_buf,
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateAdBlockClient(std::move(client), resources_json);
|
||||
UpdateAdBlockClient(std::move(client), storage);
|
||||
}
|
||||
|
||||
void AdBlockEngine::AddObserverForTest(AdBlockEngine::TestObserver* observer) {
|
||||
|
||||
@@ -55,7 +55,7 @@ class AdBlockEngine {
|
||||
const GURL& url,
|
||||
blink::mojom::ResourceType resource_type,
|
||||
const std::string& tab_host);
|
||||
void UseResources(const std::string& resources);
|
||||
void UseResources(const adblock::BraveCoreResourceStorage& storage);
|
||||
void EnableTag(const std::string& tag, bool enabled);
|
||||
bool TagExists(const std::string& tag);
|
||||
|
||||
@@ -71,9 +71,9 @@ class AdBlockEngine {
|
||||
|
||||
void Load(bool deserialize,
|
||||
const DATFileDataBuffer& dat_buf,
|
||||
const std::string& resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage);
|
||||
void Load(rust::Box<adblock::FilterSet> filter_set,
|
||||
const std::string& resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage);
|
||||
|
||||
class TestObserver : public base::CheckedObserver {
|
||||
public:
|
||||
@@ -88,14 +88,14 @@ class AdBlockEngine {
|
||||
protected:
|
||||
void AddKnownTagsToAdBlockInstance();
|
||||
void UpdateAdBlockClient(rust::Box<adblock::Engine> ad_block_client,
|
||||
const std::string& resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage);
|
||||
|
||||
void OnFilterSetLoaded(rust::Box<adblock::FilterSet> filter_set,
|
||||
const std::string& resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage);
|
||||
void OnListSourceLoaded(const DATFileDataBuffer& filters,
|
||||
const std::string& resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage);
|
||||
void OnDATLoaded(const DATFileDataBuffer& dat_buf,
|
||||
const std::string& resources_json);
|
||||
const adblock::BraveCoreResourceStorage& storage);
|
||||
|
||||
rust::Box<adblock::Engine> ad_block_client_
|
||||
GUARDED_BY_CONTEXT(sequence_checker_);
|
||||
|
||||
@@ -97,22 +97,28 @@ void AdBlockService::SourceProviderObserver::OnFilterSetCreated(
|
||||
}
|
||||
|
||||
void AdBlockService::SourceProviderObserver::OnResourcesLoaded(
|
||||
const std::string& resources_json) {
|
||||
AdblockResourceStorageBox storage) {
|
||||
if (!filter_set_) {
|
||||
task_runner_->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&AdBlockEngine::UseResources,
|
||||
adblock_engine_->AsWeakPtr(), resources_json));
|
||||
FROM_HERE, base::BindOnce(
|
||||
[](base::WeakPtr<AdBlockEngine> engine,
|
||||
AdblockResourceStorageBox storage) {
|
||||
if (engine) {
|
||||
engine->UseResources(*storage);
|
||||
}
|
||||
},
|
||||
adblock_engine_->AsWeakPtr(), std::move(storage)));
|
||||
} else {
|
||||
auto engine_load_callback = base::BindOnce(
|
||||
[](base::WeakPtr<AdBlockEngine> engine,
|
||||
std::unique_ptr<rust::Box<adblock::FilterSet>> filter_set,
|
||||
const std::string& resources_json) {
|
||||
AdblockResourceStorageBox storage) {
|
||||
if (engine) {
|
||||
engine->Load(std::move(*filter_set.get()), resources_json);
|
||||
engine->Load(std::move(*filter_set.get()), *storage);
|
||||
}
|
||||
},
|
||||
adblock_engine_->AsWeakPtr(), std::move(filter_set_), resources_json);
|
||||
adblock_engine_->AsWeakPtr(), std::move(filter_set_),
|
||||
std::move(storage));
|
||||
task_runner_->PostTask(FROM_HERE, std::move(engine_load_callback));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ class AdBlockService {
|
||||
void OnChanged(bool is_default_engine) override;
|
||||
|
||||
// AdBlockResourceProvider::Observer
|
||||
void OnResourcesLoaded(const std::string& resources_json) override;
|
||||
void OnResourcesLoaded(AdblockResourceStorageBox) override;
|
||||
|
||||
std::unique_ptr<rust::Box<adblock::FilterSet>> filter_set_;
|
||||
raw_ptr<AdBlockEngine> adblock_engine_ = nullptr; // not owned
|
||||
|
||||
@@ -41,7 +41,6 @@ static_library("browser") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//brave/components/brave_component_updater/browser",
|
||||
"//brave/components/brave_shields/core/browser/adblock",
|
||||
"//brave/components/brave_shields/core/common",
|
||||
"//brave/components/brave_shields/core/common:mojom",
|
||||
"//brave/components/constants",
|
||||
@@ -60,7 +59,10 @@ static_library("browser") {
|
||||
"//crypto",
|
||||
"//url",
|
||||
]
|
||||
public_deps = [ "//base" ]
|
||||
public_deps = [
|
||||
"//base",
|
||||
"//brave/components/brave_shields/core/browser/adblock",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("unit_tests") {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "base/check_is_test.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "brave/components/brave_shields/core/browser/brave_shields_utils.h"
|
||||
@@ -85,29 +84,7 @@ base::Value::List::iterator FindResource(base::Value::List& resources,
|
||||
});
|
||||
}
|
||||
|
||||
std::string_view JsonListStr(std::string_view json) {
|
||||
const auto start = json.find('[');
|
||||
const auto end = json.rfind(']');
|
||||
if (start == std::string_view::npos || end == std::string_view::npos ||
|
||||
start >= end) {
|
||||
return std::string_view();
|
||||
}
|
||||
return json.substr(start + 1, end - start - 1);
|
||||
}
|
||||
|
||||
std::string MergeResources(const std::string& default_resources,
|
||||
const std::string& custom_resources) {
|
||||
auto default_resources_str = JsonListStr(default_resources);
|
||||
if (default_resources_str.empty()) {
|
||||
return custom_resources;
|
||||
}
|
||||
auto custom_resources_str = JsonListStr(custom_resources);
|
||||
if (custom_resources_str.empty()) {
|
||||
return default_resources;
|
||||
}
|
||||
return base::StrCat(
|
||||
{"[", default_resources_str, ",", custom_resources_str, "]"});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -203,18 +180,18 @@ void AdBlockCustomResourceProvider::RemoveObserver(
|
||||
}
|
||||
|
||||
void AdBlockCustomResourceProvider::LoadResources(
|
||||
base::OnceCallback<void(const std::string& resources_json)> on_load) {
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> on_load) {
|
||||
default_resource_provider_->LoadResources(
|
||||
base::BindOnce(&AdBlockCustomResourceProvider::OnDefaultResourcesLoaded,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(on_load)));
|
||||
}
|
||||
|
||||
void AdBlockCustomResourceProvider::OnResourcesLoaded(
|
||||
const std::string& resources_json) {
|
||||
AdblockResourceStorageBox storage) {
|
||||
OnDefaultResourcesLoaded(
|
||||
base::BindOnce(&AdBlockCustomResourceProvider::NotifyResourcesLoaded,
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
resources_json);
|
||||
std::move(storage));
|
||||
}
|
||||
|
||||
void AdBlockCustomResourceProvider::AddResourceInternal(
|
||||
@@ -286,28 +263,29 @@ void AdBlockCustomResourceProvider::SaveResources(base::Value resources) {
|
||||
}
|
||||
|
||||
void AdBlockCustomResourceProvider::OnDefaultResourcesLoaded(
|
||||
base::OnceCallback<void(const std::string& resources_json)> on_load,
|
||||
const std::string& resources_json) {
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> on_load,
|
||||
AdblockResourceStorageBox storage) {
|
||||
GetCustomResources(base::BindOnce(
|
||||
&AdBlockCustomResourceProvider::OnCustomResourcesLoaded,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(on_load), resources_json));
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(on_load), std::move(storage)));
|
||||
}
|
||||
|
||||
void AdBlockCustomResourceProvider::OnCustomResourcesLoaded(
|
||||
base::OnceCallback<void(const std::string& resources_json)> on_load,
|
||||
const std::string& default_resources_json,
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> on_load,
|
||||
AdblockResourceStorageBox default_storage,
|
||||
base::Value custom_resources) {
|
||||
CHECK(custom_resources.is_list());
|
||||
|
||||
if (custom_resources.GetList().empty()) {
|
||||
std::move(on_load).Run(default_resources_json);
|
||||
std::move(on_load).Run(std::move(default_storage));
|
||||
} else {
|
||||
auto custom_resources_json = base::WriteJson(custom_resources);
|
||||
if (!custom_resources_json) {
|
||||
std::move(on_load).Run(default_resources_json);
|
||||
std::move(on_load).Run(std::move(default_storage));
|
||||
} else {
|
||||
std::move(on_load).Run(
|
||||
MergeResources(default_resources_json, *custom_resources_json));
|
||||
auto merged_storage = adblock::extend_resource_storage(
|
||||
*default_storage, *custom_resources_json);
|
||||
std::move(on_load).Run(std::move(merged_storage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,11 +64,11 @@ class AdBlockCustomResourceProvider
|
||||
|
||||
// AdBlockResourceProvider:
|
||||
void LoadResources(
|
||||
base::OnceCallback<void(const std::string& resources_json)>) override;
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)>) override;
|
||||
|
||||
private:
|
||||
// AdBlockResourceProvider::Observer:
|
||||
void OnResourcesLoaded(const std::string& resources_json) override;
|
||||
void OnResourcesLoaded(AdblockResourceStorageBox) override;
|
||||
|
||||
void AddResourceInternal(base::Value resource,
|
||||
StatusCallback on_complete,
|
||||
@@ -84,11 +84,11 @@ class AdBlockCustomResourceProvider
|
||||
void SaveResources(base::Value resources);
|
||||
|
||||
void OnDefaultResourcesLoaded(
|
||||
base::OnceCallback<void(const std::string& resources_json)> on_load,
|
||||
const std::string& resources_json);
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> on_load,
|
||||
AdblockResourceStorageBox storage);
|
||||
void OnCustomResourcesLoaded(
|
||||
base::OnceCallback<void(const std::string& resources_json)> on_load,
|
||||
const std::string& default_resources,
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> on_load,
|
||||
AdblockResourceStorageBox default_storage,
|
||||
base::Value custom_resources);
|
||||
|
||||
void ReloadResourcesAndNotify();
|
||||
|
||||
+17
-24
@@ -5,12 +5,13 @@
|
||||
|
||||
#include "brave/components/brave_shields/core/browser/ad_block_custom_resource_provider.h"
|
||||
|
||||
#include "base/base64.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "base/test/test_future.h"
|
||||
#include "base/values.h"
|
||||
#include "brave/components/brave_shields/core/browser/adblock/rs/src/lib.rs.h"
|
||||
#include "brave/components/brave_shields/core/common/features.h"
|
||||
#include "brave/components/brave_shields/core/common/pref_names.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
@@ -25,7 +26,7 @@ base::Value CreateResource(const std::string& name,
|
||||
const std::string& content) {
|
||||
base::Value::Dict resource;
|
||||
resource.Set("name", name);
|
||||
resource.Set("content", content);
|
||||
resource.Set("content", base::Base64Encode(content));
|
||||
resource.SetByDottedPath("kind.mime", "application/javascript");
|
||||
return base::Value(std::move(resource));
|
||||
}
|
||||
@@ -35,9 +36,10 @@ class TestResourceProvider : public AdBlockResourceProvider {
|
||||
TestResourceProvider() = default;
|
||||
~TestResourceProvider() override = default;
|
||||
|
||||
void LoadResources(base::OnceCallback<void(const std::string& resources_json)>
|
||||
on_load) override {
|
||||
std::move(on_load).Run(resources_json_);
|
||||
void LoadResources(
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> on_load) override {
|
||||
auto storage = adblock::new_resource_storage(resources_json_);
|
||||
std::move(on_load).Run(std::move(storage));
|
||||
}
|
||||
|
||||
void SetResources(const std::string& resources_json) {
|
||||
@@ -111,14 +113,11 @@ class AdBlockCustomResourceProviderTest : public ::testing::Test {
|
||||
return result.Take();
|
||||
}
|
||||
|
||||
base::Value LoadResources() {
|
||||
base::test::TestFuture<const std::string&> result;
|
||||
bool HasResource(const std::string& name) {
|
||||
base::test::TestFuture<AdblockResourceStorageBox> result;
|
||||
custom_resource_provider()->LoadResources(result.GetCallback());
|
||||
if (result.Get().empty()) {
|
||||
return base::Value(base::ListValue());
|
||||
}
|
||||
return *base::JSONReader::Read(result.Take(),
|
||||
base::JSON_PARSE_CHROMIUM_EXTENSIONS);
|
||||
auto storage = result.Take();
|
||||
return adblock::has_resource_for_testing(*storage, name);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -264,29 +263,23 @@ TEST_F(AdBlockCustomResourceProviderTest, UpdateResource) {
|
||||
}
|
||||
|
||||
TEST_F(AdBlockCustomResourceProviderTest, LoadResource) {
|
||||
EXPECT_EQ(base::ListValue(), LoadResources());
|
||||
EXPECT_FALSE(HasResource("default-1.js"));
|
||||
|
||||
default_resource_provider()->SetResources(
|
||||
base::ListValue()
|
||||
.Append(CreateResource("default-1.js", "default-1"))
|
||||
.DebugString());
|
||||
|
||||
EXPECT_EQ(
|
||||
base::ListValue().Append(CreateResource("default-1.js", "default-1")),
|
||||
LoadResources());
|
||||
EXPECT_TRUE(HasResource("default-1.js"));
|
||||
|
||||
prefs()->SetBoolean(prefs::kAdBlockDeveloperMode, true);
|
||||
AddResource(CreateResource("user-1.js", "user-1"));
|
||||
EXPECT_EQ(base::ListValue()
|
||||
.Append(CreateResource("default-1.js", "default-1"))
|
||||
.Append(CreateResource("user-1.js", "user-1")),
|
||||
LoadResources());
|
||||
EXPECT_TRUE(HasResource("default-1.js"));
|
||||
EXPECT_TRUE(HasResource("user-1.js"));
|
||||
|
||||
prefs()->SetBoolean(prefs::kAdBlockDeveloperMode, false);
|
||||
EXPECT_EQ(base::ListValue()
|
||||
.Append(CreateResource("default-1.js", "default-1"))
|
||||
.Append(CreateResource("user-1.js", "user-1")),
|
||||
LoadResources());
|
||||
EXPECT_TRUE(HasResource("default-1.js"));
|
||||
EXPECT_TRUE(HasResource("user-1.js"));
|
||||
}
|
||||
|
||||
} // namespace brave_shields
|
||||
|
||||
@@ -55,22 +55,31 @@ void AdBlockDefaultResourceProvider::OnComponentReady(
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the resources (as a string)
|
||||
// Load the resources (as ResourceStorage)
|
||||
base::ThreadPool::PostTaskAndReplyWithResult(
|
||||
FROM_HERE, {base::MayBlock()},
|
||||
base::BindOnce(&brave_component_updater::GetDATFileAsString,
|
||||
resources_path),
|
||||
base::BindOnce(&AdBlockDefaultResourceProvider::NotifyResourcesLoaded,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
base::BindOnce(
|
||||
[](base::WeakPtr<AdBlockDefaultResourceProvider> provider,
|
||||
const std::string& resources_json) {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
auto storage = adblock::new_resource_storage(resources_json);
|
||||
provider->NotifyResourcesLoaded(std::move(storage));
|
||||
},
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void AdBlockDefaultResourceProvider::LoadResources(
|
||||
base::OnceCallback<void(const std::string& resources_json)> cb) {
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)> cb) {
|
||||
base::FilePath resources_path = GetResourcesPath();
|
||||
if (resources_path.empty()) {
|
||||
// If the path is not ready yet, run the callback with empty resources to
|
||||
// avoid blocking filter data loads.
|
||||
std::move(cb).Run("[]");
|
||||
auto empty_storage = adblock::new_empty_resource_storage();
|
||||
std::move(cb).Run(std::move(empty_storage));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,7 +87,13 @@ void AdBlockDefaultResourceProvider::LoadResources(
|
||||
FROM_HERE, {base::MayBlock()},
|
||||
base::BindOnce(&brave_component_updater::GetDATFileAsString,
|
||||
resources_path),
|
||||
std::move(cb));
|
||||
base::BindOnce(
|
||||
[](base::OnceCallback<void(AdblockResourceStorageBox)> cb,
|
||||
const std::string& resources_json) {
|
||||
auto storage = adblock::new_resource_storage(resources_json);
|
||||
std::move(cb).Run(std::move(storage));
|
||||
},
|
||||
std::move(cb)));
|
||||
}
|
||||
|
||||
} // namespace brave_shields
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_CORE_BROWSER_AD_BLOCK_DEFAULT_RESOURCE_PROVIDER_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_SHIELDS_CORE_BROWSER_AD_BLOCK_DEFAULT_RESOURCE_PROVIDER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "brave/components/brave_shields/core/browser/ad_block_resource_provider.h"
|
||||
|
||||
@@ -37,7 +35,7 @@ class AdBlockDefaultResourceProvider : public AdBlockResourceProvider {
|
||||
base::FilePath GetResourcesPath();
|
||||
|
||||
void LoadResources(
|
||||
base::OnceCallback<void(const std::string& resources_json)>) override;
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)>) override;
|
||||
|
||||
private:
|
||||
friend class ::AdBlockServiceTest;
|
||||
|
||||
@@ -28,9 +28,9 @@ void AdBlockResourceProvider::RemoveObserver(
|
||||
}
|
||||
|
||||
void AdBlockResourceProvider::NotifyResourcesLoaded(
|
||||
const std::string& resources_json) {
|
||||
AdblockResourceStorageBox storage) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.OnResourcesLoaded(resources_json);
|
||||
observer.OnResourcesLoaded(adblock::clone_resource_storage(*storage));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,24 +6,26 @@
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_SHIELDS_CORE_BROWSER_AD_BLOCK_RESOURCE_PROVIDER_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_SHIELDS_CORE_BROWSER_AD_BLOCK_RESOURCE_PROVIDER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/observer_list_types.h"
|
||||
#include "brave/components/brave_component_updater/browser/dat_file_util.h"
|
||||
#include "brave/components/brave_shields/core/browser/adblock/rs/src/lib.rs.h"
|
||||
|
||||
using brave_component_updater::DATFileDataBuffer;
|
||||
|
||||
namespace brave_shields {
|
||||
|
||||
// C++ type alias for rust BraveCoreResourceStorage.
|
||||
using AdblockResourceStorageBox = rust::Box<adblock::BraveCoreResourceStorage>;
|
||||
|
||||
// Interface for any source that can load resource replacements into an adblock
|
||||
// engine.
|
||||
class AdBlockResourceProvider {
|
||||
public:
|
||||
class Observer : public base::CheckedObserver {
|
||||
public:
|
||||
virtual void OnResourcesLoaded(const std::string& resources_json) = 0;
|
||||
virtual void OnResourcesLoaded(AdblockResourceStorageBox) = 0;
|
||||
};
|
||||
|
||||
AdBlockResourceProvider();
|
||||
@@ -33,10 +35,10 @@ class AdBlockResourceProvider {
|
||||
void RemoveObserver(Observer* observer);
|
||||
|
||||
virtual void LoadResources(
|
||||
base::OnceCallback<void(const std::string& resources_json)>) = 0;
|
||||
base::OnceCallback<void(AdblockResourceStorageBox)>) = 0;
|
||||
|
||||
protected:
|
||||
void NotifyResourcesLoaded(const std::string& resources_json);
|
||||
void NotifyResourcesLoaded(AdblockResourceStorageBox);
|
||||
|
||||
private:
|
||||
base::ObserverList<Observer> observers_;
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::str::Utf8Error;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::resource_storage::BraveCoreResourceStorage;
|
||||
use adblock::lists::FilterSet as InnerFilterSet;
|
||||
use adblock::resources::{InMemoryResourceStorage, Resource};
|
||||
use adblock::url_parser::ResolvesDomain;
|
||||
use adblock::Engine as InnerEngine;
|
||||
use cxx::{let_cxx_string, CxxString, CxxVector};
|
||||
@@ -195,21 +193,8 @@ impl Engine {
|
||||
self.engine.deserialize(serialized.as_slice()).is_ok()
|
||||
}
|
||||
|
||||
// TODO(https://github.com/brave/brave-browser/issues/50368): remove this method, expose storage API.
|
||||
pub fn use_resources(&mut self, resources_json: &CxxString) -> bool {
|
||||
resources_json
|
||||
.to_str()
|
||||
.ok()
|
||||
.and_then(|resources_json| serde_json::from_str::<Vec<Resource>>(resources_json).ok())
|
||||
.and_then(|resources| {
|
||||
let in_memory_storage = InMemoryResourceStorage::from_resources(resources);
|
||||
let shared_storage = Arc::new(in_memory_storage);
|
||||
let bc_storage = BraveCoreResourceStorage { shared_storage };
|
||||
|
||||
self.engine.use_resource_storage(bc_storage);
|
||||
Some(())
|
||||
})
|
||||
.is_some()
|
||||
pub fn use_resource_storage(&mut self, storage: &BraveCoreResourceStorage) {
|
||||
self.engine.use_resource_storage(storage.clone());
|
||||
}
|
||||
|
||||
pub fn url_cosmetic_resources(&self, url: &CxxString) -> String {
|
||||
|
||||
@@ -14,6 +14,7 @@ mod result;
|
||||
|
||||
use engine::*;
|
||||
use filter_set::*;
|
||||
use resource_storage::*;
|
||||
|
||||
#[allow(unsafe_op_in_unsafe_fn)]
|
||||
#[cxx::bridge(namespace = adblock)]
|
||||
@@ -28,6 +29,19 @@ mod ffi {
|
||||
permission_mask: u8,
|
||||
) -> FilterListMetadataResult;
|
||||
}
|
||||
extern "Rust" {
|
||||
type BraveCoreResourceStorage;
|
||||
fn new_resource_storage(resources_json: &CxxString) -> Box<BraveCoreResourceStorage>;
|
||||
fn new_empty_resource_storage() -> Box<BraveCoreResourceStorage>;
|
||||
fn clone_resource_storage(
|
||||
storage: &BraveCoreResourceStorage,
|
||||
) -> Box<BraveCoreResourceStorage>;
|
||||
fn extend_resource_storage(
|
||||
storage: &BraveCoreResourceStorage,
|
||||
additional_resources_json: &str,
|
||||
) -> Box<BraveCoreResourceStorage>;
|
||||
fn has_resource_for_testing(storage: &BraveCoreResourceStorage, name: &CxxString) -> bool;
|
||||
}
|
||||
extern "Rust" {
|
||||
type Engine;
|
||||
/// Creates a new engine with no rules.
|
||||
@@ -77,8 +91,8 @@ mod ffi {
|
||||
pub fn serialize(&self) -> Vec<u8>;
|
||||
/// Deserializes and loads a binary-serialized Engine.
|
||||
fn deserialize(&mut self, serialized: &CxxVector<u8>) -> bool;
|
||||
/// Loads JSON-serialized resources into the engine resource set.
|
||||
fn use_resources(&mut self, resources_json: &CxxString) -> bool;
|
||||
/// Loads resources from a ResourceStorage instance into the engine.
|
||||
fn use_resource_storage(&mut self, storage: &BraveCoreResourceStorage);
|
||||
/// Returns JSON-serialized cosmetic filter resources for a given url.
|
||||
fn url_cosmetic_resources(&self, url: &CxxString) -> String;
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use adblock::resources::{InMemoryResourceStorage, ResourceImpl, ResourceStorageBackend};
|
||||
use adblock::resources::{InMemoryResourceStorage, Resource, ResourceImpl, ResourceStorageBackend};
|
||||
use cxx::CxxString;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A wrapper around the inner storage to share ownership of the inner storage.
|
||||
#[derive(Clone)]
|
||||
pub struct BraveCoreResourceStorage {
|
||||
pub shared_storage: Arc<InMemoryResourceStorage>,
|
||||
shared_storage: Arc<InMemoryResourceStorage>,
|
||||
}
|
||||
|
||||
impl ResourceStorageBackend for BraveCoreResourceStorage {
|
||||
@@ -16,3 +18,49 @@ impl ResourceStorageBackend for BraveCoreResourceStorage {
|
||||
self.shared_storage.get_resource(resource_ident)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ResourceStorage from JSON string.
|
||||
pub fn new_resource_storage(resources_json: &CxxString) -> Box<BraveCoreResourceStorage> {
|
||||
let resources = serde_json::from_str::<Vec<Resource>>(resources_json.to_str().unwrap_or("[]"))
|
||||
.unwrap_or_default();
|
||||
let in_memory_storage = InMemoryResourceStorage::from_resources(resources);
|
||||
let shared_storage = Arc::new(in_memory_storage);
|
||||
Box::new(BraveCoreResourceStorage { shared_storage })
|
||||
}
|
||||
|
||||
/// Creates a new empty ResourceStorage.
|
||||
pub fn new_empty_resource_storage() -> Box<BraveCoreResourceStorage> {
|
||||
let in_memory_storage = InMemoryResourceStorage::from_resources(vec![]);
|
||||
let shared_storage = Arc::new(in_memory_storage);
|
||||
Box::new(BraveCoreResourceStorage { shared_storage })
|
||||
}
|
||||
|
||||
/// Clones a BraveCoreResourceStorage.
|
||||
/// Clones only the Arc-based wrapper, the inner storage remains shared.
|
||||
pub fn clone_resource_storage(storage: &BraveCoreResourceStorage) -> Box<BraveCoreResourceStorage> {
|
||||
Box::new(storage.clone())
|
||||
}
|
||||
|
||||
/// Clones and extends a storage with additional resources.
|
||||
pub fn extend_resource_storage(
|
||||
storage: &BraveCoreResourceStorage,
|
||||
additional_resources_json: &str,
|
||||
) -> Box<BraveCoreResourceStorage> {
|
||||
if let Ok(additional_resources) =
|
||||
serde_json::from_str::<Vec<Resource>>(additional_resources_json)
|
||||
{
|
||||
if !additional_resources.is_empty() {
|
||||
let mut inner_storage = storage.shared_storage.as_ref().clone();
|
||||
|
||||
for resource in additional_resources {
|
||||
let _ = inner_storage.add_resource(resource);
|
||||
}
|
||||
return Box::new(BraveCoreResourceStorage { shared_storage: Arc::new(inner_storage) });
|
||||
}
|
||||
}
|
||||
clone_resource_storage(storage)
|
||||
}
|
||||
|
||||
pub fn has_resource_for_testing(storage: &BraveCoreResourceStorage, name: &CxxString) -> bool {
|
||||
storage.get_resource(name.to_str().unwrap_or("")).is_some()
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ extension AdblockService {
|
||||
/// Get a stream of resource component updates
|
||||
@MainActor fileprivate func resourcesComponentStream() -> AsyncStream<URL> {
|
||||
return AsyncStream { continuation in
|
||||
registerResourcesChanges { [weak self] _ in
|
||||
registerResourcesChanges { [weak self] in
|
||||
guard let resourcesPath = self?.resourcesPath else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -216,7 +216,12 @@ class AdblockEngineBox final {
|
||||
}
|
||||
|
||||
- (bool)useResources:(NSString*)resources {
|
||||
return adblock_engine->use_resources(base::SysNSStringToUTF8(resources));
|
||||
// TODO(https://github.com/brave/brave-browser/issues/51103):
|
||||
// Reuse the once created storage for the both engines.
|
||||
auto storage =
|
||||
adblock::new_resource_storage(base::SysNSStringToUTF8(resources));
|
||||
adblock_engine->use_resource_storage(*storage);
|
||||
return true;
|
||||
}
|
||||
|
||||
- (NSString*)cosmeticResourcesForURL:(NSString*)url {
|
||||
|
||||
@@ -37,7 +37,7 @@ OBJC_EXPORT
|
||||
- (void)registerCatalogChanges:(void (^)())callback;
|
||||
|
||||
/// Listen to downloaded version changes of resources
|
||||
- (void)registerResourcesChanges:(void (^)(NSString* resourcesJSON))callback;
|
||||
- (void)registerResourcesChanges:(void (^)())callback;
|
||||
|
||||
/// Update the filter lists
|
||||
- (void)updateFilterLists:(void (^)(bool))callback;
|
||||
|
||||
@@ -30,8 +30,7 @@ namespace brave_shields {
|
||||
using OnFilterListUpdatedCallback =
|
||||
base::RepeatingCallback<void(bool is_default_engine)>;
|
||||
using OnFilterListCatalogLoadedCallback = base::RepeatingCallback<void()>;
|
||||
using OnResourceUpdatedCallback =
|
||||
base::RepeatingCallback<void(const std::string& resources_json)>;
|
||||
using OnResourceUpdatedCallback = base::RepeatingCallback<void()>;
|
||||
|
||||
/// This class listens to changes in the adblock filters provider and notifies
|
||||
class AdBlockServiceObserver : public AdBlockFiltersProvider::Observer {
|
||||
@@ -79,7 +78,7 @@ class AdBlockResourceObserver : public AdBlockResourceProvider::Observer {
|
||||
explicit AdBlockResourceObserver(OnResourceUpdatedCallback callback);
|
||||
|
||||
// AdBlockFilterListCatalogProvider::Observer
|
||||
void OnResourcesLoaded(const std::string& resources_json) override;
|
||||
void OnResourcesLoaded(AdblockResourceStorageBox) override;
|
||||
|
||||
private:
|
||||
OnResourceUpdatedCallback callback_;
|
||||
@@ -90,9 +89,10 @@ AdBlockResourceObserver::AdBlockResourceObserver(
|
||||
: callback_(callback) {}
|
||||
|
||||
void AdBlockResourceObserver::OnResourcesLoaded(
|
||||
const std::string& resources_json) {
|
||||
callback_.Run(resources_json);
|
||||
AdblockResourceStorageBox /*storage*/) {
|
||||
callback_.Run();
|
||||
}
|
||||
|
||||
} // namespace brave_shields
|
||||
|
||||
@interface AdblockService () {
|
||||
@@ -155,12 +155,10 @@ void AdBlockResourceObserver::OnResourcesLoaded(
|
||||
_catalogProvider->AddObserver(_catalogObserver.get());
|
||||
}
|
||||
|
||||
- (void)registerResourcesChanges:(void (^)(NSString* resourcesJSON))callback {
|
||||
- (void)registerResourcesChanges:(void (^)())callback {
|
||||
_resourceObserver = std::make_unique<brave_shields::AdBlockResourceObserver>(
|
||||
base::BindRepeating(^(const std::string& resources_json) {
|
||||
const auto resourcesJSON = base::SysUTF8ToNSString(resources_json);
|
||||
callback(resourcesJSON);
|
||||
}));
|
||||
base::BindRepeating(callback));
|
||||
|
||||
_resourceProvider->AddObserver(_resourceObserver.get());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user