| Index: chrome/browser/extensions/extension_event_router.cc
|
| diff --git a/chrome/browser/extensions/extension_event_router.cc b/chrome/browser/extensions/extension_event_router.cc
|
| index 21c315c90242fdea08875992bd9f0962a1df4d93..5fb2dfd21e6e63b71b4afe37dcb9b75335bebd6f 100644
|
| --- a/chrome/browser/extensions/extension_event_router.cc
|
| +++ b/chrome/browser/extensions/extension_event_router.cc
|
| @@ -119,10 +119,57 @@ ExtensionEventRouter::ExtensionEventRouter(Profile* profile)
|
|
|
| ExtensionEventRouter::~ExtensionEventRouter() {}
|
|
|
| +bool ExtensionEventRouter::IsEventAvailable(
|
| + const std::string& event_name,
|
| + const std::string& extension_id,
|
| + content::RenderProcessHost* render_process,
|
| + Feature::Context context_type) const {
|
| + ExtensionService* extension_service = profile_->GetExtensionService();
|
| + const Extension* extension =
|
| + extension_service->extensions()->GetByID(extension_id);
|
| + if (!extension)
|
| + return false;
|
| +
|
| + ExtensionAPI* api = ExtensionAPI::GetSharedInstance();
|
| +
|
| + // If the API has been ported to the feature system, use that.
|
| + if (api->GetFeature(event_name)) {
|
| + if (!api->IsAvailable(
|
| + event_name,
|
| + extension,
|
| + static_cast<Feature::Context>(context_type))) {
|
| + LOG(ERROR) << "Access to extension API '" << event_name << "' denied.";
|
| + return false;
|
| + }
|
| + } else {
|
| + // Otherwise, fall back to the older system.
|
| + // TODO(aa): Remove this when all APIs have been ported.
|
| + if (!extension->HasAPIPermission(event_name)) {
|
| + LOG(ERROR) << "Extension " << extension->id() << " does not have "
|
| + << "permission to event: " << event_name;
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // If the API requires a privileged process, ensure it is in one.
|
| + if (api->IsPrivileged(event_name) &&
|
| + !extension_service->process_map()->Contains(extension->id(),
|
| + render_process->GetID())) {
|
| + LOG(ERROR) << "Extension API called from incorrect process";
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| void ExtensionEventRouter::AddEventListener(
|
| const std::string& event_name,
|
| + const std::string& extension_id,
|
| content::RenderProcessHost* process,
|
| - const std::string& extension_id) {
|
| + Feature::Context context_type) {
|
| + if (!IsEventAvailable(event_name, extension_id, process, context_type))
|
| + return;
|
| +
|
| ListenerProcess listener(process, extension_id);
|
| DCHECK_EQ(listeners_[event_name].count(listener), 0u) << event_name;
|
| listeners_[event_name].insert(listener);
|
| @@ -167,6 +214,15 @@ void ExtensionEventRouter::RemoveEventListener(
|
|
|
| void ExtensionEventRouter::AddLazyEventListener(
|
| const std::string& event_name,
|
| + const std::string& extension_id,
|
| + content::RenderProcessHost* render_process,
|
| + Feature::Context context_type) {
|
| + if (!IsEventAvailable(event_name, extension_id, render_process, context_type))
|
| + AddLazyEventListener(event_name, extension_id);
|
| +}
|
| +
|
| +void ExtensionEventRouter::AddLazyEventListener(
|
| + const std::string& event_name,
|
| const std::string& extension_id) {
|
| ListenerProcess lazy_listener(NULL, extension_id);
|
| bool is_new = lazy_listeners_[event_name].insert(lazy_listener).second;
|
| @@ -312,15 +368,6 @@ void ExtensionEventRouter::DispatchEventToListener(
|
|
|
| Profile* listener_profile = Profile::FromBrowserContext(
|
| listener.process->GetBrowserContext());
|
| - extensions::ProcessMap* process_map =
|
| - listener_profile->GetExtensionService()->process_map();
|
| - // If the event is privileged, only send to extension processes. Otherwise,
|
| - // it's OK to send to normal renderers (e.g., for content scripts).
|
| - if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) &&
|
| - !process_map->Contains(extension->id(), listener.process->GetID())) {
|
| - return;
|
| - }
|
| -
|
| const std::string* event_args;
|
| if (!CanDispatchEventToProfile(listener_profile, extension,
|
| event, &event_args))
|
|
|