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