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

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: Fixed browser_tests build 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/rules_cache_delegate.h" 12 #include "chrome/browser/extensions/api/declarative/rules_cache_delegate.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);
35 }
36
37 bool IsWebView(const RulesRegistryService::WebViewKey& webview_key) {
38 return webview_key.first && webview_key.second;
31 } 39 }
32 40
33 } // namespace 41 } // namespace
34 42
35 RulesRegistryService::RulesRegistryService(Profile* profile) 43 RulesRegistryService::RulesRegistryService(Profile* profile)
36 : content_rules_registry_(NULL), 44 : content_rules_registry_(NULL),
37 profile_(profile) { 45 profile_(profile) {
38 if (profile) { 46 if (profile) {
39 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 47 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
40 content::Source<Profile>(profile->GetOriginalProfile())); 48 content::Source<Profile>(profile->GetOriginalProfile()));
41 RegisterDefaultRulesRegistries(); 49 registrar_.Add(
50 this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
51 content::NotificationService::AllBrowserContextsAndSources());
52 RegisterDefaultRulesRegistriesIfNotAvailable(WebViewKey(0, 0));
42 } 53 }
43 } 54 }
44 55
45 RulesRegistryService::~RulesRegistryService() {} 56 RulesRegistryService::~RulesRegistryService() {}
46 57
47 void RulesRegistryService::RegisterDefaultRulesRegistries() { 58 void RulesRegistryService::RegisterDefaultRulesRegistriesIfNotAvailable(
48 scoped_ptr<RulesCacheDelegate> web_request_cache_delegate( 59 const WebViewKey& webview_key) {
49 new RulesCacheDelegate(true /*log_storage_init_delay*/)); 60 if (!profile_)
61 return;
62
63 RulesRegistryKey key(declarative_webrequest_constants::kOnRequest,
64 webview_key);
65 RulesRegistryMap::const_iterator i = rule_registries_.find(key);
Jeffrey Yasskin 2013/11/09 02:47:22 If you don't use this iterator again, use Contains
Fady Samuel 2013/11/10 03:39:56 Done.
66 // If we can find the key in the |rule_registries_| then we have already
67 // installed the default registries.
68 if (i != rule_registries_.end())
69 return;
70
71
72 RulesCacheDelegate* web_request_cache_delegate = NULL;
73 if (!IsWebView(webview_key)) {
74 web_request_cache_delegate =
75 new RulesCacheDelegate(true /*log_storage_init_delay*/);
76 cache_delegates_.push_back(web_request_cache_delegate);
77 }
50 scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry( 78 scoped_refptr<WebRequestRulesRegistry> web_request_rules_registry(
51 new WebRequestRulesRegistry(profile_, web_request_cache_delegate.get())); 79 new WebRequestRulesRegistry(profile_,
52 cache_delegates_.push_back(web_request_cache_delegate.release()); 80 web_request_cache_delegate,
81 webview_key));
53 82
54 RegisterRulesRegistry(web_request_rules_registry); 83 RegisterRulesRegistry(web_request_rules_registry);
55 content::BrowserThread::PostTask( 84 content::BrowserThread::PostTask(
56 content::BrowserThread::IO, FROM_HERE, 85 content::BrowserThread::IO, FROM_HERE,
57 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, 86 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO,
58 profile_, web_request_rules_registry)); 87 profile_, webview_key, web_request_rules_registry));
59 88
60 #if defined(ENABLE_EXTENSIONS) 89 #if defined(ENABLE_EXTENSIONS)
61 scoped_ptr<RulesCacheDelegate> content_rules_cache_delegate( 90 // Only create a ContentRulesRegistry for regular pages and not webviews.
62 new RulesCacheDelegate(false /*log_storage_init_delay*/)); 91 if (!IsWebView(webview_key)) {
63 scoped_refptr<ContentRulesRegistry> content_rules_registry( 92 RulesCacheDelegate* content_rules_cache_delegate =
64 new ContentRulesRegistry(profile_, content_rules_cache_delegate.get())); 93 new RulesCacheDelegate(false /*log_storage_init_delay*/);
65 cache_delegates_.push_back(content_rules_cache_delegate.release()); 94 cache_delegates_.push_back(content_rules_cache_delegate);
66 95 scoped_refptr<ContentRulesRegistry> content_rules_registry(
67 RegisterRulesRegistry(content_rules_registry); 96 new ContentRulesRegistry(profile_, content_rules_cache_delegate));
68 content_rules_registry_ = content_rules_registry.get(); 97 RegisterRulesRegistry(content_rules_registry);
98 content_rules_registry_ = content_rules_registry.get();
99 }
69 #endif // defined(ENABLE_EXTENSIONS) 100 #endif // defined(ENABLE_EXTENSIONS)
70 } 101 }
71 102
72 void RulesRegistryService::Shutdown() { 103 void RulesRegistryService::Shutdown() {
73 // Release the references to all registries. This would happen soon during 104 // Release the references to all registries. This would happen soon during
74 // destruction of |*this|, but we need the ExtensionWebRequestEventRouter to 105 // destruction of |*this|, but we need the ExtensionWebRequestEventRouter to
75 // be the last to reference the WebRequestRulesRegistry objects, so that 106 // be the last to reference the WebRequestRulesRegistry objects, so that
76 // the posted task below causes their destruction on the IO thread, not on UI 107 // the posted task below causes their destruction on the IO thread, not on UI
77 // where the destruction of |*this| takes place. 108 // where the destruction of |*this| takes place.
78 // TODO(vabr): Remove once http://crbug.com/218451#c6 gets addressed. 109 // TODO(vabr): Remove once http://crbug.com/218451#c6 gets addressed.
79 rule_registries_.clear(); 110 rule_registries_.clear();
80 content::BrowserThread::PostTask( 111 content::BrowserThread::PostTask(
81 content::BrowserThread::IO, FROM_HERE, 112 content::BrowserThread::IO, FROM_HERE,
82 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO, 113 base::Bind(&RegisterToExtensionWebRequestEventRouterOnIO,
83 profile_, scoped_refptr<WebRequestRulesRegistry>(NULL))); 114 profile_, WebViewKey(0, 0),
115 scoped_refptr<WebRequestRulesRegistry>(NULL)));
84 } 116 }
85 117
86 static base::LazyInstance<ProfileKeyedAPIFactory<RulesRegistryService> > 118 static base::LazyInstance<ProfileKeyedAPIFactory<RulesRegistryService> >
87 g_factory = LAZY_INSTANCE_INITIALIZER; 119 g_factory = LAZY_INSTANCE_INITIALIZER;
88 120
89 // static 121 // static
90 ProfileKeyedAPIFactory<RulesRegistryService>* 122 ProfileKeyedAPIFactory<RulesRegistryService>*
91 RulesRegistryService::GetFactoryInstance() { 123 RulesRegistryService::GetFactoryInstance() {
92 return &g_factory.Get(); 124 return &g_factory.Get();
93 } 125 }
94 126
95 // static 127 // static
96 RulesRegistryService* RulesRegistryService::Get(Profile* profile) { 128 RulesRegistryService* RulesRegistryService::Get(Profile* profile) {
97 return ProfileKeyedAPIFactory<RulesRegistryService>::GetForProfile(profile); 129 return ProfileKeyedAPIFactory<RulesRegistryService>::GetForProfile(profile);
98 } 130 }
99 131
100 void RulesRegistryService::RegisterRulesRegistry( 132 void RulesRegistryService::RegisterRulesRegistry(
101 scoped_refptr<RulesRegistry> rule_registry) { 133 scoped_refptr<RulesRegistry> rule_registry) {
102 const std::string event_name(rule_registry->event_name()); 134 const std::string event_name(rule_registry->event_name());
103 DCHECK(rule_registries_.find(event_name) == rule_registries_.end()); 135 RulesRegistryKey key(event_name, rule_registry->webview_key());
104 rule_registries_[event_name] = rule_registry; 136 DCHECK(rule_registries_.find(key) == rule_registries_.end());
137 rule_registries_[key] = rule_registry;
105 } 138 }
106 139
107 scoped_refptr<RulesRegistry> RulesRegistryService::GetRulesRegistry( 140 scoped_refptr<RulesRegistry> RulesRegistryService::GetRulesRegistry(
108 const std::string& event_name) const { 141 const WebViewKey& webview_key,
109 RulesRegistryMap::const_iterator i = rule_registries_.find(event_name); 142 const std::string& event_name) {
143 RegisterDefaultRulesRegistriesIfNotAvailable(webview_key);
144
145 RulesRegistryKey key(event_name, webview_key);
146 RulesRegistryMap::const_iterator i = rule_registries_.find(key);
110 if (i == rule_registries_.end()) 147 if (i == rule_registries_.end())
111 return scoped_refptr<RulesRegistry>(); 148 return scoped_refptr<RulesRegistry>();
112 return i->second; 149 return i->second;
113 } 150 }
114 151
152 void RulesRegistryService::RemoveWebViewRulesRegistries(int process_id) {
153 DCHECK_NE(0, process_id);
154
155 RulesRegistryKeySet registries_to_delete;
156 for (RulesRegistryMap::iterator it = rule_registries_.begin();
157 it != rule_registries_.end(); ++it) {
158 const RulesRegistryKey& key = it->first;
159 const WebViewKey& webview_key = key.second;
160 int embedder_process_id = webview_key.first;
161 // |process_id| will always be non-zero.
162 // |embedder_process_id| will only be non-zero if the key corresponds to a
163 // webview registry.
164 // Thus, |embedder_process_id| == |process_id| ==> the process ID is a
165 // webview embedder.
166 if (embedder_process_id != process_id)
167 continue;
168
169 // Modifying the container while iterating is bad so we'll save the keys we
170 // wish to delete in another container, and delete them in another loop.
171 registries_to_delete.insert(key);
172 }
173 for (RulesRegistryKeySet::iterator it = registries_to_delete.begin();
174 it != registries_to_delete.end(); ++it) {
175 RemoveRulesRegistry(*it);
176 }
177 }
178
115 void RulesRegistryService::SimulateExtensionUnloaded( 179 void RulesRegistryService::SimulateExtensionUnloaded(
116 const std::string& extension_id) { 180 const std::string& extension_id) {
117 OnExtensionUnloaded(extension_id); 181 OnExtensionUnloaded(extension_id);
118 } 182 }
119 183
120 void RulesRegistryService::OnExtensionUnloaded( 184 void RulesRegistryService::OnExtensionUnloaded(
121 const std::string& extension_id) { 185 const std::string& extension_id) {
122 RulesRegistryMap::iterator i; 186 RulesRegistryMap::iterator i;
123 for (i = rule_registries_.begin(); i != rule_registries_.end(); ++i) { 187 for (i = rule_registries_.begin(); i != rule_registries_.end(); ++i) {
124 scoped_refptr<RulesRegistry> registry = i->second; 188 scoped_refptr<RulesRegistry> registry = i->second;
125 if (content::BrowserThread::CurrentlyOn(registry->owner_thread())) { 189 if (content::BrowserThread::CurrentlyOn(registry->owner_thread())) {
126 registry->OnExtensionUnloaded(extension_id); 190 registry->OnExtensionUnloaded(extension_id);
127 } else { 191 } else {
128 content::BrowserThread::PostTask( 192 content::BrowserThread::PostTask(
129 registry->owner_thread(), 193 registry->owner_thread(),
130 FROM_HERE, 194 FROM_HERE,
131 base::Bind( 195 base::Bind(
132 &RulesRegistry::OnExtensionUnloaded, registry, extension_id)); 196 &RulesRegistry::OnExtensionUnloaded, registry, extension_id));
133 } 197 }
134 } 198 }
135 } 199 }
136 200
201 void RulesRegistryService::RemoveRulesRegistry(const RulesRegistryKey& key) {
Jeffrey Yasskin 2013/11/09 02:47:22 Unless this is called from multiple places, I'd ju
Fady Samuel 2013/11/10 03:39:56 Done.
202 rule_registries_.erase(key);
203 }
204
137 void RulesRegistryService::Observe( 205 void RulesRegistryService::Observe(
138 int type, 206 int type,
139 const content::NotificationSource& source, 207 const content::NotificationSource& source,
140 const content::NotificationDetails& details) { 208 const content::NotificationDetails& details) {
141 switch (type) { 209 switch (type) {
142 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 210 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
143 const Extension* extension = 211 const Extension* extension =
144 content::Details<UnloadedExtensionInfo>(details)->extension; 212 content::Details<UnloadedExtensionInfo>(details)->extension;
145 OnExtensionUnloaded(extension->id()); 213 OnExtensionUnloaded(extension->id());
146 break; 214 break;
147 } 215 }
216 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
217 content::RenderProcessHost* process =
218 content::Source<content::RenderProcessHost>(source).ptr();
219 RemoveWebViewRulesRegistries(process->GetID());
220 break;
221 }
148 default: 222 default:
149 NOTREACHED(); 223 NOTREACHED();
150 break; 224 break;
151 } 225 }
152 } 226 }
153 227
154 } // namespace extensions 228 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698