-
Notifications
You must be signed in to change notification settings - Fork 842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decouple adblock engines from component loading methods #10994
Conversation
aa460f7
to
89125c8
Compare
void AdBlockCustomFiltersSourceProvider::Load( | ||
base::OnceCallback<void(bool deserialize, const DATFileDataBuffer& dat_buf)> | ||
cb) { | ||
content::GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is still called on more than one thread which is not safe. Also usage of base::Unretained is not safe here. Each class should be called on one and only one thread. The only exception is that a class can be created on one thread and then used on a different thread after that. I think it's best to add thread checks to enforce that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also avoid the use of named task runners like UIThread
const base::FilePath& path) { | ||
component_path_ = path; | ||
|
||
base::ThreadPool::PostTaskAndReplyWithResult( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would break these out into separate method calls and add comments to clarify what is happening
@@ -0,0 +1,45 @@ | |||
/* Copyright (c) 2021 The Brave Authors. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file name should match the class name
89125c8
to
6ec06d4
Compare
void AdBlockRegionalSourceProvider::Load( | ||
base::OnceCallback<void(bool deserialize, const DATFileDataBuffer& dat_buf)> | ||
cb) { | ||
if (component_path_.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not ok to just ignore the callback
public: | ||
class Observer : public base::CheckedObserver { | ||
public: | ||
virtual void OnNewResourcesAvailable(const std::string& resources_json) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these aren't "new" resources, I would call this OnLoaded
or something
@@ -253,49 +266,85 @@ void AdBlockBaseService::OnGetDATFileData(base::OnceClosure callback, | |||
return; | |||
} | |||
GetTaskRunner()->PostTask( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't be using a task runner for anything anymore. AdBlockEngineService
should only run on one thread
AdBlockDefaultSourceProvider::AdBlockDefaultSourceProvider( | ||
component_updater::ComponentUpdateService* cus, | ||
base::RepeatingCallback<void(const std::string& regional_catalog)> | ||
regional_catalog_available_cb) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is there a separate callback for this?
const DATFileDataBuffer& dat_buf)>) = 0; | ||
|
||
protected: | ||
void ProvideNewDAT(const DATFileDataBuffer& dat_buf); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The convention for this would be OnDATLoaded, but I'm confused about why ListSource is also a DATFileDataBuffer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to pass the list source across the Rust FFI as a buffer as well because it's a potentially untrusted/invalid input. The FFI will attempt to parse it to a string, and handle it correspondingly if it doesn't parse correctly.
public: | ||
class Observer : public base::CheckedObserver { | ||
public: | ||
virtual void OnNewDATAvailable(const DATFileDataBuffer& dat_buf) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as below, this should be OnDATLoaded
or OnDATReady
component_update_service_(cus), | ||
task_runner_(task_runner), | ||
subscription_service_manager_(std::move(subscription_service_manager)) { | ||
default_source_provider_ = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the source provider should be owned by browser_process_impl and passed in to the AdBlockService
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, it doesn't necessarily need to be owned by browser_process_impl right now, but it should be created in browser_process_impl and passed in
default_source_provider_ = | ||
std::make_unique<brave_shields::AdBlockDefaultSourceProvider>( | ||
component_update_service_, | ||
base::BindRepeating(&AdBlockService::OnRegionalCatalogFileDataReady, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AdBlockService should register as an observer for the SourceProvider
return custom_filters_service_.get(); | ||
} | ||
|
||
brave_shields::AdBlockCustomFiltersSourceProvider* | ||
AdBlockService::custom_filters_source_provider() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing outside of this class should ever need access to the custom_filters_source_provider
@@ -61,27 +60,28 @@ std::unique_ptr<DomainBlockNavigationThrottle> | |||
DomainBlockNavigationThrottle::MaybeCreateThrottleFor( | |||
content::NavigationHandle* navigation_handle, | |||
AdBlockService* ad_block_service, | |||
AdBlockCustomFiltersService* ad_block_custom_filters_service, | |||
AdBlockCustomFiltersSourceProvider* ad_block_custom_filters_source_provider, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is definitely not right, why are we passing in the source provider?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same reason as #10994 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're missing what I'm saying, the SourceProvider shouldn't be passed to other classes, they should only deal with the service.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess my reasoning is that there isn't a CustomFiltersService
in the current implementation; just the engine and SourceProvider. The method to add the new custom filter could be added to AdBlockService in the current implementation, or adding CustomFiltersService to handle it could work too.
ad_block_custom_filters_service_->GetCustomFilters(); | ||
ad_block_custom_filters_service_->UpdateCustomFilters( | ||
ad_block_custom_filters_source_provider_->GetCustomFilters(); | ||
ad_block_custom_filters_source_provider_->UpdateCustomFilters( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we're actually modifying the filter to disable the rule? That's definitely not great, but a separate issue from this PR. Can you open a ticket for that? In any case these methods should be called on the service, not the source provider and DomainBlockControllerClient
shouldn't have to know anything about the rules format. We should just be calling ad_block_custom_filters_service_->DisableRule(request_url_.host())
or something along those lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed a followup at brave/brave-browser#19863
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but both this class and DomainBlockNavigationThrottle should only ever talk to the service and shouldn't know anything about the underlying source provider so you should pass the service here and add methods to pass through to the source provider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 !
@@ -104,16 +104,17 @@ std::string ResourceTypeToString(blink::mojom::ResourceType resource_type) { | |||
|
|||
namespace brave_shields { | |||
|
|||
AdBlockBaseService::AdBlockBaseService(BraveComponent::Delegate* delegate) | |||
: BaseBraveShieldsService(delegate), | |||
AdBlockEngineService::AdBlockEngineService( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should drop Service
here, it's very confusing
if (cus) { | ||
RegisterAdBlockDefaultComponent( | ||
cus, | ||
base::BindRepeating(&AdBlockDefaultSourceProvider::OnComponentReady, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this causes the SourceProvider to be called on more than one thread because OnComponentReady
is called on the UI thread and Load is called from the adblock thread
} | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
|
||
std::unique_ptr<AdBlockEngineService> AdBlockEngineServiceFactory( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method serves no useful purpose
regional_catalog_available_cb); | ||
~AdBlockDefaultSourceProvider() override; | ||
|
||
void Load(base::OnceCallback< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't overload method names that do different things. One of these loads a dat file and the other loads resources
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are technically overridden from AdBlockSourceProvider
and AdBlockResourceProvider
respectively; they make sense in context there but maybe not when overloaded side-by-side. I can rename to LoadDATBuffer
and LoadResources
respectively
f3015a9
to
761c204
Compare
initialized_ = true; | ||
} | ||
|
||
AdBlockRegionalServiceManager::~AdBlockRegionalServiceManager() {} | ||
AdBlockRegionalServiceManager::~AdBlockRegionalServiceManager() { | ||
catalog_provider_->RemoveObserver(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls prefer ScopedObservation
, for future reference
790525e
to
e2b5b59
Compare
e2b5b59
to
391d032
Compare
This method was only useful for the old extension-based cosmetic filtering implementation, and has started causing some tests to fail on the newer C++ implementation.
Resolves brave/brave-browser#19366
Submitter Checklist:
QA/Yes
orQA/No
;release-notes/include
orrelease-notes/exclude
;OS/...
) to the associated issuenpm run test -- brave_browser_tests
,npm run test -- brave_unit_tests
,npm run lint
,npm run gn_check
,npm run tslint
git rebase master
(if needed)Reviewer Checklist:
gn
After-merge Checklist:
changes has landed on
Test Plan:
This is a fairly large refactoring that shouldn't change any existing behavior. The automated unit and browser tests cover most core functionality, but it would be great to go over test plans related to previously-merged adblock-related PRs and ensure that things still work the same way. In particular, that updated adblock rules are applied, whether that be the default set of rules, regional lists, custom filters, or custom list subscriptions.