Chromium Code Reviews| Index: chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| diff --git a/chrome/browser/extensions/api/declarative/rules_registry_service.cc b/chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| index a0685d07e717b3997fba969a0468d2c111716baf..003470aab05d027b1ea3c1e8593f5236e8d03376 100644 |
| --- a/chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| +++ b/chrome/browser/extensions/api/declarative/rules_registry_service.cc |
| @@ -11,12 +11,15 @@ |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/api/declarative/rules_cache_delegate.h" |
| #include "chrome/browser/extensions/api/declarative_content/content_rules_registry.h" |
| +#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" |
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" |
| #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.h" |
| +#include "content/public/browser/render_process_host.h" |
| namespace extensions { |
| @@ -25,9 +28,14 @@ namespace { |
| // Registers |web_request_rules_registry| on the IO thread. |
| void RegisterToExtensionWebRequestEventRouterOnIO( |
| void* profile, |
| + const RulesRegistryService::WebViewKey& webview_key, |
| scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry) { |
| ExtensionWebRequestEventRouter::GetInstance()->RegisterRulesRegistry( |
| - profile, web_request_rules_registry); |
| + profile, webview_key, web_request_rules_registry); |
| +} |
| + |
| +bool IsWebView(const RulesRegistryService::WebViewKey& webview_key) { |
| + return webview_key.first && webview_key.second; |
| } |
| } // namespace |
| @@ -38,34 +46,57 @@ RulesRegistryService::RulesRegistryService(Profile* profile) |
| if (profile) { |
| registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| content::Source<Profile>(profile->GetOriginalProfile())); |
| - RegisterDefaultRulesRegistries(); |
| + registrar_.Add( |
| + this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| + content::NotificationService::AllBrowserContextsAndSources()); |
| + RegisterDefaultRulesRegistriesIfNotAvailable(WebViewKey(0, 0)); |
| } |
| } |
| RulesRegistryService::~RulesRegistryService() {} |
| -void RulesRegistryService::RegisterDefaultRulesRegistries() { |
| - scoped_ptr<RulesCacheDelegate> web_request_cache_delegate( |
| - new RulesCacheDelegate(true /*log_storage_init_delay*/)); |
| +void RulesRegistryService::RegisterDefaultRulesRegistriesIfNotAvailable( |
| + const WebViewKey& webview_key) { |
| + if (!profile_) |
| + return; |
| + |
| + RulesRegistryKey key(declarative_webrequest_constants::kOnRequest, |
| + webview_key); |
| + RulesRegistryMap::const_iterator i = rule_registries_.find(key); |
| + // If we can find the key in the |rule_registries_| then we have already |
| + // installed the default registries. |
| + if (i != rule_registries_.end()) |
| + return; |
| + |
| + |
| + RulesCacheDelegate* web_request_cache_delegate = NULL; |
| + if (!IsWebView(webview_key)) { |
| + web_request_cache_delegate = |
| + new RulesCacheDelegate(true /*log_storage_init_delay*/); |
| + cache_delegates_.push_back(web_request_cache_delegate); |
| + } |
| scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( |
| - new WebRequestRulesRegistry(profile_, web_request_cache_delegate.get())); |
| - cache_delegates_.push_back(web_request_cache_delegate.release()); |
| + new WebRequestRulesRegistry(profile_, |
| + web_request_cache_delegate, |
| + webview_key)); |
| RegisterRulesRegistry(web_request_rules_registry); |
| content::BrowserThread::PostTask( |
| content::BrowserThread::IO, FROM_HERE, |
| base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, |
| - profile_, web_request_rules_registry)); |
| + profile_, webview_key, web_request_rules_registry)); |
| #if defined(ENABLE_EXTENSIONS) |
| - scoped_ptr<RulesCacheDelegate> content_rules_cache_delegate( |
| - new RulesCacheDelegate(false /*log_storage_init_delay*/)); |
| - scoped_refptr<ContentRulesRegistry> content_rules_registry( |
| - new ContentRulesRegistry(profile_, content_rules_cache_delegate.get())); |
| - cache_delegates_.push_back(content_rules_cache_delegate.release()); |
| - |
| - RegisterRulesRegistry(content_rules_registry); |
| - content_rules_registry_ = content_rules_registry.get(); |
| + // Only create a ContentRulesRegistry for regular pages and not webviews. |
| + if (!IsWebView(webview_key)) { |
| + RulesCacheDelegate* content_rules_cache_delegate = |
| + new RulesCacheDelegate(false /*log_storage_init_delay*/); |
| + cache_delegates_.push_back(content_rules_cache_delegate); |
| + scoped_refptr<ContentRulesRegistry> content_rules_registry( |
| + new ContentRulesRegistry(profile_, content_rules_cache_delegate)); |
| + RegisterRulesRegistry(content_rules_registry); |
| + content_rules_registry_ = content_rules_registry.get(); |
| + } |
| #endif // defined(ENABLE_EXTENSIONS) |
| } |
| @@ -80,7 +111,8 @@ void RulesRegistryService::Shutdown() { |
| content::BrowserThread::PostTask( |
| content::BrowserThread::IO, FROM_HERE, |
| base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, |
| - profile_, scoped_refptr<WebRequestRulesRegistry>(NULL))); |
| + profile_, WebViewKey(0, 0), |
| + scoped_refptr<WebRequestRulesRegistry>(NULL))); |
| } |
| static base::LazyInstance<ProfileKeyedAPIFactory<RulesRegistryService> > |
| @@ -100,18 +132,58 @@ RulesRegistryService* RulesRegistryService::Get(Profile* profile) { |
| void RulesRegistryService::RegisterRulesRegistry( |
| scoped_refptr<RulesRegistry> rule_registry) { |
| const std::string event_name(rule_registry->event_name()); |
| - DCHECK(rule_registries_.find(event_name) == rule_registries_.end()); |
| - rule_registries_[event_name] = rule_registry; |
| + RulesRegistryKey key(event_name, rule_registry->webview_key()); |
| + DCHECK(rule_registries_.find(key) == rule_registries_.end()); |
| + rule_registries_[key] = rule_registry; |
| } |
| scoped_refptr<RulesRegistry> RulesRegistryService::GetRulesRegistry( |
| - const std::string& event_name) const { |
| - RulesRegistryMap::const_iterator i = rule_registries_.find(event_name); |
| + const WebViewKey& webview_key, |
| + const std::string& event_name) { |
| + RegisterDefaultRulesRegistriesIfNotAvailable(webview_key); |
| + |
| + RulesRegistryKey key(event_name, webview_key); |
| + RulesRegistryMap::const_iterator i = rule_registries_.find(key); |
| if (i == rule_registries_.end()) |
| return scoped_refptr<RulesRegistry>(); |
| return i->second; |
| } |
| +ContentRulesRegistry* RulesRegistryService::GetContentRulesRegistry() { |
| + if (!content_rules_registry_) { |
|
vabr (Chromium)
2013/11/04 11:12:13
We construct the content rules registry in the Rul
Fady Samuel
2013/11/04 20:13:53
Done.
|
| + WebViewKey webview_key(0, 0); |
| + RegisterDefaultRulesRegistriesIfNotAvailable(webview_key); |
| + } |
| + return content_rules_registry_; |
| +} |
| + |
| +void RulesRegistryService::RemoveWebViewRulesRegistries(int process_id) { |
| + DCHECK_NE(0, process_id); |
| + |
| + RulesRegistryKeySet registries_to_delete; |
| + for (RulesRegistryMap::iterator it = rule_registries_.begin(); |
| + it != rule_registries_.end(); ++it) { |
| + const RulesRegistryKey& key = it->first; |
| + const WebViewKey& webview_key = key.second; |
| + int embedder_process_id = webview_key.first; |
| + // |process_id| will always be non-zero. |
| + // |embedder_process_id| will only be non-zero if the key corresponds to a |
| + // webview registry. |
| + // Thus, |embedder_process_id| == |process_id| ==> the process ID is a |
| + // webview embedder. |
| + if (embedder_process_id != process_id) |
| + continue; |
| + |
| + // Modifying the container while iterating is bad so we'll save the keys we |
| + // wish to delete in another container, and delete them in another loop. |
| + registries_to_delete.insert(key); |
| + } |
| + for (RulesRegistryKeySet::iterator it = registries_to_delete.begin(); |
| + it != registries_to_delete.end(); ++it) { |
| + RemoveRulesRegistry(*it); |
| + } |
| +} |
| + |
| void RulesRegistryService::SimulateExtensionUnloaded( |
| const std::string& extension_id) { |
| OnExtensionUnloaded(extension_id); |
| @@ -134,6 +206,10 @@ void RulesRegistryService::OnExtensionUnloaded( |
| } |
| } |
| +void RulesRegistryService::RemoveRulesRegistry(const RulesRegistryKey& key) { |
| + rule_registries_.erase(key); |
| +} |
| + |
| void RulesRegistryService::Observe( |
| int type, |
| const content::NotificationSource& source, |
| @@ -145,6 +221,12 @@ void RulesRegistryService::Observe( |
| OnExtensionUnloaded(extension->id()); |
| break; |
| } |
| + case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { |
| + content::RenderProcessHost* process = |
| + content::Source<content::RenderProcessHost>(source).ptr(); |
| + RemoveWebViewRulesRegistries(process->GetID()); |
| + break; |
| + } |
| default: |
| NOTREACHED(); |
| break; |