Chromium Code Reviews

Side by Side Diff: chrome/browser/extensions/extension_event_router.cc

Issue 10025007: Convert tabs, windows, and extension APIs to feature system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: blah Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
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/extension_event_router.h" 5 #include "chrome/browser/extensions/extension_event_router.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "chrome/browser/extensions/api/runtime/runtime_api.h" 10 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
(...skipping 101 matching lines...)
112 content::Source<Profile>(profile_)); 112 content::Source<Profile>(profile_));
113 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 113 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
114 content::Source<Profile>(profile_)); 114 content::Source<Profile>(profile_));
115 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, 115 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
116 content::Source<Profile>(profile_)); 116 content::Source<Profile>(profile_));
117 // TODO(tessamac): also get notified for background page crash/failure. 117 // TODO(tessamac): also get notified for background page crash/failure.
118 } 118 }
119 119
120 ExtensionEventRouter::~ExtensionEventRouter() {} 120 ExtensionEventRouter::~ExtensionEventRouter() {}
121 121
122 bool ExtensionEventRouter::IsEventAvailable(
123 const std::string& event_name,
124 const std::string& extension_id,
125 content::RenderProcessHost* render_process,
126 Feature::Context context_type) const {
127 ExtensionService* extension_service = profile_->GetExtensionService();
128 const Extension* extension =
129 extension_service->extensions()->GetByID(extension_id);
130 if (!extension)
131 return false;
132
133 ExtensionAPI* api = ExtensionAPI::GetSharedInstance();
134
135 // If the API has been ported to the feature system, use that.
136 if (api->GetFeature(event_name)) {
137 if (!api->IsAvailable(
138 event_name,
139 extension,
140 static_cast<Feature::Context>(context_type))) {
141 LOG(ERROR) << "Access to extension API '" << event_name << "' denied.";
142 return false;
143 }
144 } else {
145 // Otherwise, fall back to the older system.
146 // TODO(aa): Remove this when all APIs have been ported.
147 if (!extension->HasAPIPermission(event_name)) {
148 LOG(ERROR) << "Extension " << extension->id() << " does not have "
149 << "permission to event: " << event_name;
150 return false;
151 }
152 }
153
154 // If the API requires a privileged process, ensure it is in one.
155 if (api->IsPrivileged(event_name) &&
156 !extension_service->process_map()->Contains(extension->id(),
157 render_process->GetID())) {
158 LOG(ERROR) << "Extension API called from incorrect process";
159 return false;
160 }
161
162 return true;
163 }
164
122 void ExtensionEventRouter::AddEventListener( 165 void ExtensionEventRouter::AddEventListener(
123 const std::string& event_name, 166 const std::string& event_name,
167 const std::string& extension_id,
124 content::RenderProcessHost* process, 168 content::RenderProcessHost* process,
125 const std::string& extension_id) { 169 Feature::Context context_type) {
170 if (!IsEventAvailable(event_name, extension_id, process, context_type))
171 return;
172
126 ListenerProcess listener(process, extension_id); 173 ListenerProcess listener(process, extension_id);
127 DCHECK_EQ(listeners_[event_name].count(listener), 0u) << event_name; 174 DCHECK_EQ(listeners_[event_name].count(listener), 0u) << event_name;
128 listeners_[event_name].insert(listener); 175 listeners_[event_name].insert(listener);
129 176
130 if (extension_devtools_manager_.get()) 177 if (extension_devtools_manager_.get())
131 extension_devtools_manager_->AddEventListener(event_name, 178 extension_devtools_manager_->AddEventListener(event_name,
132 process->GetID()); 179 process->GetID());
133 180
134 // We lazily tell the TaskManager to start updating when listeners to the 181 // We lazily tell the TaskManager to start updating when listeners to the
135 // processes.onUpdated event arrive. 182 // processes.onUpdated event arrive.
(...skipping 24 matching lines...)
160 207
161 BrowserThread::PostTask( 208 BrowserThread::PostTask(
162 BrowserThread::IO, FROM_HERE, 209 BrowserThread::IO, FROM_HERE,
163 base::Bind( 210 base::Bind(
164 &NotifyEventListenerRemovedOnIOThread, 211 &NotifyEventListenerRemovedOnIOThread,
165 profile_, listener.extension_id, event_name)); 212 profile_, listener.extension_id, event_name));
166 } 213 }
167 214
168 void ExtensionEventRouter::AddLazyEventListener( 215 void ExtensionEventRouter::AddLazyEventListener(
169 const std::string& event_name, 216 const std::string& event_name,
217 const std::string& extension_id,
218 content::RenderProcessHost* render_process,
219 Feature::Context context_type) {
220 if (!IsEventAvailable(event_name, extension_id, render_process, context_type))
221 AddLazyEventListener(event_name, extension_id);
222 }
223
224 void ExtensionEventRouter::AddLazyEventListener(
225 const std::string& event_name,
170 const std::string& extension_id) { 226 const std::string& extension_id) {
171 ListenerProcess lazy_listener(NULL, extension_id); 227 ListenerProcess lazy_listener(NULL, extension_id);
172 bool is_new = lazy_listeners_[event_name].insert(lazy_listener).second; 228 bool is_new = lazy_listeners_[event_name].insert(lazy_listener).second;
173 if (is_new) { 229 if (is_new) {
174 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); 230 ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs();
175 std::set<std::string> events = prefs->GetRegisteredEvents(extension_id); 231 std::set<std::string> events = prefs->GetRegisteredEvents(extension_id);
176 bool prefs_is_new = events.insert(event_name).second; 232 bool prefs_is_new = events.insert(event_name).second;
177 if (prefs_is_new) 233 if (prefs_is_new)
178 prefs->SetRegisteredEvents(extension_id, events); 234 prefs->SetRegisteredEvents(extension_id, events);
179 } 235 }
(...skipping 125 matching lines...)
305 const Extension* extension = service->extensions()->GetByID( 361 const Extension* extension = service->extensions()->GetByID(
306 listener.extension_id); 362 listener.extension_id);
307 363
308 // The extension could have been removed, but we do not unregister it until 364 // The extension could have been removed, but we do not unregister it until
309 // the extension process is unloaded. 365 // the extension process is unloaded.
310 if (!extension) 366 if (!extension)
311 return; 367 return;
312 368
313 Profile* listener_profile = Profile::FromBrowserContext( 369 Profile* listener_profile = Profile::FromBrowserContext(
314 listener.process->GetBrowserContext()); 370 listener.process->GetBrowserContext());
315 extensions::ProcessMap* process_map =
316 listener_profile->GetExtensionService()->process_map();
317 // If the event is privileged, only send to extension processes. Otherwise,
318 // it's OK to send to normal renderers (e.g., for content scripts).
319 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) &&
320 !process_map->Contains(extension->id(), listener.process->GetID())) {
321 return;
322 }
323
324 const std::string* event_args; 371 const std::string* event_args;
325 if (!CanDispatchEventToProfile(listener_profile, extension, 372 if (!CanDispatchEventToProfile(listener_profile, extension,
326 event, &event_args)) 373 event, &event_args))
327 return; 374 return;
328 375
329 DispatchEvent(listener.process, listener.extension_id, 376 DispatchEvent(listener.process, listener.extension_id,
330 event->event_name, *event_args, 377 event->event_name, *event_args,
331 event->event_url, event->user_gesture); 378 event->event_url, event->user_gesture);
332 IncrementInFlightEvents(listener_profile, extension); 379 IncrementInFlightEvents(listener_profile, extension);
333 } 380 }
(...skipping 155 matching lines...)
489 profile_, extension); 536 profile_, extension);
490 break; 537 break;
491 } 538 }
492 539
493 // TODO(tessamac): if background page crashed/failed clear queue. 540 // TODO(tessamac): if background page crashed/failed clear queue.
494 default: 541 default:
495 NOTREACHED(); 542 NOTREACHED();
496 return; 543 return;
497 } 544 }
498 } 545 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_event_router.h ('k') | chrome/browser/extensions/extension_function_dispatcher.cc » ('j') | no next file with comments »

Powered by Google App Engine