| 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)) | 
|  |