Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(643)

Side by Side Diff: chrome/browser/extensions/api/declarative/rules_registry_service.cc

Issue 28273006: <webview>: Implement declarativeWebRequest API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added tests Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/declarative/rules_registry_service.h" 5 #include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/api/declarative/initializing_rules_registry. h" 12 #include "chrome/browser/extensions/api/declarative/initializing_rules_registry. h"
13 #include "chrome/browser/extensions/api/declarative_content/content_rules_regist ry.h" 13 #include "chrome/browser/extensions/api/declarative_content/content_rules_regist ry.h"
14 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h"
14 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h" 15 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h"
15 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 16 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
16 #include "chrome/common/extensions/extension.h" 17 #include "chrome/common/extensions/extension.h"
17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_details.h" 19 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_source.h" 21 #include "content/public/browser/notification_source.h"
22 #include "content/public/browser/render_process_host.h"
20 23
21 namespace extensions { 24 namespace extensions {
22 25
23 namespace { 26 namespace {
24 27
25 // Registers |web_request_rules_registry| on the IO thread. 28 // Registers |web_request_rules_registry| on the IO thread.
26 void RegisterToExtensionWebRequestEventRouterOnIO( 29 void RegisterToExtensionWebRequestEventRouterOnIO(
27 void* profile, 30 void* profile,
31 const RulesRegistryService::WebViewKey& webview_key,
28 scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry) { 32 scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry) {
29 ExtensionWebRequestEventRouter::GetInstance()->RegisterRulesRegistry( 33 ExtensionWebRequestEventRouter::GetInstance()->RegisterRulesRegistry(
30 profile, web_request_rules_registry); 34 profile, webview_key, web_request_rules_registry);
31 } 35 }
32 36
33 } // namespace 37 } // namespace
34 38
35 RulesRegistryService::RulesRegistryService(Profile* profile) 39 RulesRegistryService::RulesRegistryService(Profile* profile)
36 : content_rules_registry_(NULL), 40 : content_rules_registry_(NULL),
37 profile_(profile) { 41 profile_(profile) {
38 if (profile) { 42 if (profile) {
39 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 43 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
40 content::Source<Profile>(profile->GetOriginalProfile())); 44 content::Source<Profile>(profile->GetOriginalProfile()));
41 RegisterDefaultRulesRegistries(); 45 registrar_.Add(
46 this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
47 content::NotificationService::AllBrowserContextsAndSources());
42 } 48 }
43 } 49 }
44 50
45 RulesRegistryService::~RulesRegistryService() {} 51 RulesRegistryService::~RulesRegistryService() {}
46 52
47 void RulesRegistryService::RegisterDefaultRulesRegistries() { 53 void RulesRegistryService::RegisterDefaultRulesRegistriesIfNotAvailable(
54 const WebViewKey& webview_key) {
55 if (!profile_)
56 return;
57
58 RulesRegistryKey key(declarative_webrequest_constants::kOnRequest,
59 webview_key);
60 RulesRegistryMap::const_iterator i = rule_registries_.find(key);
61 // If we can find the key in the |rule_registries_| then we have already
62 // installed the default registries.
63 if (i != rule_registries_.end())
64 return;
65
48 scoped_ptr<RulesRegistryWithCache::RuleStorageOnUI> ui_part; 66 scoped_ptr<RulesRegistryWithCache::RuleStorageOnUI> ui_part;
49 scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( 67 scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry(
50 new WebRequestRulesRegistry(profile_, &ui_part)); 68 new WebRequestRulesRegistry(profile_, &ui_part, webview_key));
51 ui_parts_of_registries_.push_back(ui_part.release()); 69 ui_parts_of_registries_.push_back(ui_part.release());
52 70
53 RegisterRulesRegistry(web_request_rules_registry); 71 RegisterRulesRegistry(web_request_rules_registry);
54 content::BrowserThread::PostTask( 72 content::BrowserThread::PostTask(
55 content::BrowserThread::IO, FROM_HERE, 73 content::BrowserThread::IO, FROM_HERE,
56 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, 74 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO,
57 profile_, web_request_rules_registry)); 75 profile_, webview_key, web_request_rules_registry));
58 76
59 #if defined(ENABLE_EXTENSIONS) 77 #if defined(ENABLE_EXTENSIONS)
60 scoped_refptr<ContentRulesRegistry> content_rules_registry( 78 // Only create a ContentRulesRegistry for regular pages and not webviews.
vabr (Chromium) 2013/10/25 20:40:24 Is this a permanent design? In that case I find it
Fady Samuel 2013/10/25 22:48:08 There are no immediate plans to support content ru
61 new ContentRulesRegistry(profile_, &ui_part)); 79 if (!webview_key.first && !webview_key.second) {
62 ui_parts_of_registries_.push_back(ui_part.release()); 80 scoped_refptr<ContentRulesRegistry> content_rules_registry(
81 new ContentRulesRegistry(profile_, &ui_part, webview_key));
82 ui_parts_of_registries_.push_back(ui_part.release());
63 83
64 RegisterRulesRegistry(content_rules_registry); 84 RegisterRulesRegistry(content_rules_registry);
65 content_rules_registry_ = content_rules_registry.get(); 85 content_rules_registry_ = content_rules_registry.get();
86 }
66 #endif // defined(ENABLE_EXTENSIONS) 87 #endif // defined(ENABLE_EXTENSIONS)
67 } 88 }
68 89
69 void RulesRegistryService::Shutdown() { 90 void RulesRegistryService::Shutdown() {
70 // Release the references to all registries. This would happen soon during 91 // Release the references to all registries. This would happen soon during
71 // destruction of |*this|, but we need the ExtensionWebRequestEventRouter to 92 // destruction of |*this|, but we need the ExtensionWebRequestEventRouter to
72 // be the last to reference the WebRequestRulesRegistry objects, so that 93 // be the last to reference the WebRequestRulesRegistry objects, so that
73 // the posted task below causes their destruction on the IO thread, not on UI 94 // the posted task below causes their destruction on the IO thread, not on UI
74 // where the destruction of |*this| takes place. 95 // where the destruction of |*this| takes place.
75 // TODO(vabr): Remove once http://crbug.com/218451#c6 gets addressed. 96 // TODO(vabr): Remove once http://crbug.com/218451#c6 gets addressed.
76 rule_registries_.clear(); 97 rule_registries_.clear();
77 content::BrowserThread::PostTask( 98 content::BrowserThread::PostTask(
78 content::BrowserThread::IO, FROM_HERE, 99 content::BrowserThread::IO, FROM_HERE,
79 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, 100 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO,
80 profile_, scoped_refptr<WebRequestRulesRegistry>(NULL))); 101 profile_, WebViewKey(0, 0),
102 scoped_refptr<WebRequestRulesRegistry>(NULL)));
81 } 103 }
82 104
83 static base::LazyInstance<ProfileKeyedAPIFactory<RulesRegistryService> > 105 static base::LazyInstance<ProfileKeyedAPIFactory<RulesRegistryService> >
84 g_factory = LAZY_INSTANCE_INITIALIZER; 106 g_factory = LAZY_INSTANCE_INITIALIZER;
85 107
86 // static 108 // static
87 ProfileKeyedAPIFactory<RulesRegistryService>* 109 ProfileKeyedAPIFactory<RulesRegistryService>*
88 RulesRegistryService::GetFactoryInstance() { 110 RulesRegistryService::GetFactoryInstance() {
89 return &g_factory.Get(); 111 return &g_factory.Get();
90 } 112 }
91 113
92 // static 114 // static
93 RulesRegistryService* RulesRegistryService::Get(Profile* profile) { 115 RulesRegistryService* RulesRegistryService::Get(Profile* profile) {
94 return ProfileKeyedAPIFactory<RulesRegistryService>::GetForProfile(profile); 116 return ProfileKeyedAPIFactory<RulesRegistryService>::GetForProfile(profile);
95 } 117 }
96 118
97 void RulesRegistryService::RegisterRulesRegistry( 119 void RulesRegistryService::RegisterRulesRegistry(
98 scoped_refptr<RulesRegistry> rule_registry) { 120 scoped_refptr<RulesRegistry> rule_registry) {
99 const std::string event_name(rule_registry->event_name()); 121 const std::string event_name(rule_registry->event_name());
100 DCHECK(rule_registries_.find(event_name) == rule_registries_.end()); 122 RulesRegistryKey key(event_name, rule_registry->webview_key());
101 rule_registries_[event_name] = 123 DCHECK(rule_registries_.find(key) == rule_registries_.end());
124 rule_registries_[key] =
102 make_scoped_refptr(new InitializingRulesRegistry(rule_registry)); 125 make_scoped_refptr(new InitializingRulesRegistry(rule_registry));
103 } 126 }
104 127
105 scoped_refptr<RulesRegistry> RulesRegistryService::GetRulesRegistry( 128 scoped_refptr<RulesRegistry> RulesRegistryService::GetRulesRegistry(
106 const std::string& event_name) const { 129 const WebViewKey& webview_key,
107 RulesRegistryMap::const_iterator i = rule_registries_.find(event_name); 130 const std::string& event_name) {
131 RegisterDefaultRulesRegistriesIfNotAvailable(webview_key);
132
133 RulesRegistryKey key(event_name, webview_key);
134 RulesRegistryMap::const_iterator i = rule_registries_.find(key);
108 if (i == rule_registries_.end()) 135 if (i == rule_registries_.end())
109 return scoped_refptr<RulesRegistry>(); 136 return scoped_refptr<RulesRegistry>();
110 return i->second; 137 return i->second;
111 } 138 }
112 139
140 ContentRulesRegistry* RulesRegistryService::GetContentRulesRegistry(
141 const WebViewKey& webview_key) {
142 RegisterDefaultRulesRegistriesIfNotAvailable(webview_key);
vabr (Chromium) 2013/10/25 20:40:24 If somebody calls this with a webview_key other th
vabr (Chromium) 2013/10/25 20:40:24 Also, is GetContentRulesRegistry called often? I'm
Fady Samuel 2013/10/25 22:48:08 Done.
Fady Samuel 2013/10/25 22:48:08 Done.
143 return content_rules_registry_;
144 }
145
146 void RulesRegistryService::RemoveWebViewRulesRegistries(int process_id) {
147 DCHECK_NE(0, process_id);
148
149 RulesRegistryKeySet registries_to_delete;
150 for (RulesRegistryMap::iterator it = rule_registries_.begin();
151 it != rule_registries_.end(); ++it) {
152 const RulesRegistryKey& key = it->first;
153 const WebViewKey& webview_key = key.second;
154 int embedder_process_id = webview_key.first;
155 // |process_id| will always be non-zero.
156 // |embedder_process_id| will only be non-zero if the key corresponds to a
157 // webview registry.
158 // Thus, |embedder_process_id| == |process_id| ==> the process ID is a
159 // webview embedder.
160 if (embedder_process_id != process_id)
161 continue;
162
163 // Modifying the container while iterating is bad so we'll save the keys we
164 // wish to delete in another container, and delete them in another loop.
165 registries_to_delete.insert(key);
vabr (Chromium) 2013/10/25 20:40:24 Is there a reason to first build the set of regist
Fady Samuel 2013/10/25 22:48:08 Yes, I am iterating over a map |rules_registries_|
vabr (Chromium) 2013/10/28 14:46:09 Ah, good point. That's all right then.
166 }
167 for (RulesRegistryKeySet::iterator it = registries_to_delete.begin();
168 it != registries_to_delete.end(); ++it) {
169 RemoveRulesRegistry(*it);
170 }
171 }
172
113 void RulesRegistryService::SimulateExtensionUnloaded( 173 void RulesRegistryService::SimulateExtensionUnloaded(
114 const std::string& extension_id) { 174 const std::string& extension_id) {
115 OnExtensionUnloaded(extension_id); 175 OnExtensionUnloaded(extension_id);
116 } 176 }
117 177
118 void RulesRegistryService::OnExtensionUnloaded( 178 void RulesRegistryService::OnExtensionUnloaded(
119 const std::string& extension_id) { 179 const std::string& extension_id) {
120 RulesRegistryMap::iterator i; 180 RulesRegistryMap::iterator i;
121 for (i = rule_registries_.begin(); i != rule_registries_.end(); ++i) { 181 for (i = rule_registries_.begin(); i != rule_registries_.end(); ++i) {
122 scoped_refptr<RulesRegistry> registry = i->second; 182 scoped_refptr<RulesRegistry> registry = i->second;
123 if (content::BrowserThread::CurrentlyOn(registry->owner_thread())) { 183 if (content::BrowserThread::CurrentlyOn(registry->owner_thread())) {
124 registry->OnExtensionUnloaded(extension_id); 184 registry->OnExtensionUnloaded(extension_id);
125 } else { 185 } else {
126 content::BrowserThread::PostTask( 186 content::BrowserThread::PostTask(
127 registry->owner_thread(), 187 registry->owner_thread(),
128 FROM_HERE, 188 FROM_HERE,
129 base::Bind( 189 base::Bind(
130 &RulesRegistry::OnExtensionUnloaded, registry, extension_id)); 190 &RulesRegistry::OnExtensionUnloaded, registry, extension_id));
131 } 191 }
132 } 192 }
133 } 193 }
134 194
195 void RulesRegistryService::RemoveRulesRegistry(const RulesRegistryKey& key) {
196 rule_registries_.erase(key);
197 }
198
135 void RulesRegistryService::Observe( 199 void RulesRegistryService::Observe(
136 int type, 200 int type,
137 const content::NotificationSource& source, 201 const content::NotificationSource& source,
138 const content::NotificationDetails& details) { 202 const content::NotificationDetails& details) {
139 switch (type) { 203 switch (type) {
140 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 204 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
141 const Extension* extension = 205 const Extension* extension =
142 content::Details<UnloadedExtensionInfo>(details)->extension; 206 content::Details<UnloadedExtensionInfo>(details)->extension;
143 OnExtensionUnloaded(extension->id()); 207 OnExtensionUnloaded(extension->id());
144 break; 208 break;
145 } 209 }
210 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
211 content::RenderProcessHost* process =
212 content::Source<content::RenderProcessHost>(source).ptr();
213 RemoveWebViewRulesRegistries(process->GetID());
214 break;
215 }
146 default: 216 default:
147 NOTREACHED(); 217 NOTREACHED();
148 break; 218 break;
149 } 219 }
150 } 220 }
151 221
152 } // namespace extensions 222 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698