15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/declarative/rules_registry_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/lazy_instance.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/declarative/initializing_rules_registry.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/declarative_content/content_rules_registry.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_request/web_request_api.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Registers |web_request_rules_registry| on the IO thread. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RegisterToExtensionWebRequestEventRouterOnIO( 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* profile, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionWebRequestEventRouter::GetInstance()->RegisterRulesRegistry( 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile, web_request_rules_registry); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RulesRegistryService::RulesRegistryService(Profile* profile) 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : content_rules_registry_(NULL), 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile_(profile) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::Source<Profile>(profile->GetOriginalProfile())); 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RegisterDefaultRulesRegistries(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RulesRegistryService::~RulesRegistryService() {} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RulesRegistryService::RegisterDefaultRulesRegistries() { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<RulesRegistryWithCache::RuleStorageOnUI> ui_part; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new WebRequestRulesRegistry(profile_, &ui_part)); 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_parts_of_registries_.push_back(ui_part.release()); 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RegisterRulesRegistry(web_request_rules_registry); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::IO, FROM_HERE, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_, web_request_rules_registry)); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ContentRulesRegistry> content_rules_registry( 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new ContentRulesRegistry(profile_, &ui_part)); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_parts_of_registries_.push_back(ui_part.release()); 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RegisterRulesRegistry(content_rules_registry); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_rules_registry_ = content_rules_registry.get(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(ENABLE_EXTENSIONS) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RulesRegistryService::Shutdown() { 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Release the references to all registries. This would happen soon during 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // destruction of |*this|, but we need the ExtensionWebRequestEventRouter to 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // be the last to reference the WebRequestRulesRegistry objects, so that 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the posted task below causes their destruction on the IO thread, not on UI 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // where the destruction of |*this| takes place. 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(vabr): Remove once http://crbug.com/218451#c6 gets addressed. 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rule_registries_.clear(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::IO, FROM_HERE, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_, scoped_refptr<WebRequestRulesRegistry>(NULL))); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static base::LazyInstance<ProfileKeyedAPIFactory<RulesRegistryService> > 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)g_factory = LAZY_INSTANCE_INITIALIZER; 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ProfileKeyedAPIFactory<RulesRegistryService>* 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)RulesRegistryService::GetFactoryInstance() { 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return &g_factory.Get(); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)RulesRegistryService* RulesRegistryService::Get(Profile* profile) { 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return ProfileKeyedAPIFactory<RulesRegistryService>::GetForProfile(profile); 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RulesRegistryService::RegisterRulesRegistry( 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<RulesRegistry> rule_registry) { 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string event_name(rule_registry->event_name()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(rule_registries_.find(event_name) == rule_registries_.end()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_registries_[event_name] = 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(new InitializingRulesRegistry(rule_registry)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<RulesRegistry> RulesRegistryService::GetRulesRegistry( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name) const { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RulesRegistryMap::const_iterator i = rule_registries_.find(event_name); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == rule_registries_.end()) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_refptr<RulesRegistry>(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i->second; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RulesRegistryService::SimulateExtensionUnloaded( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExtensionUnloaded(extension_id); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RulesRegistryService::OnExtensionUnloaded( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RulesRegistryMap::iterator i; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = rule_registries_.begin(); i != rule_registries_.end(); ++i) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<RulesRegistry> registry = i->second; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (content::BrowserThread::CurrentlyOn(registry->owner_thread())) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry->OnExtensionUnloaded(extension_id); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask( 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->owner_thread(), 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind( 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &RulesRegistry::OnExtensionUnloaded, registry, extension_id)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RulesRegistryService::Observe( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<UnloadedExtensionInfo>(details)->extension; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExtensionUnloaded(extension->id()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 153