15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/profiler/scoped_profile.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/child_process_security_policy.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/api_activity_monitor.h" 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_host.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/browser/lazy_background_task_queue.h" 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/notification_types.h" 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_manager.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_map.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "extensions/common/extension_api.h" 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "extensions/common/extension_urls.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/incognito_info.h" 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using base::DictionaryValue; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using base::ListValue; 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::BrowserContext; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void DoNothing(ExtensionHost* host) {} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// A dictionary of event names to lists of filters that this extension has 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// registered from its lazy background page. 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kFilteredEvents[] = "filtered_events"; 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Sends a notification about an event to the API activity monitor on the 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// UI thread. Can be called from any thread. 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotifyApiEventDispatched(void* browser_context_id, 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extension_id, 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& event_name, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ListValue> args) { 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The ApiActivityMonitor can only be accessed from the UI thread. 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&NotifyApiEventDispatched, 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) browser_context_id, 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_name, 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&args))); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Notify the ApiActivityMonitor about the event dispatch. 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserContext* context = static_cast<BrowserContext*>(browser_context_id); 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ExtensionsBrowserClient::Get()->IsValidContext(context)) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ApiActivityMonitor* monitor = 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionsBrowserClient::Get()->GetApiActivityMonitor(context); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (monitor) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitor->OnApiEventDispatched(extension_id, event_name, args.Pass()); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char EventRouter::kRegisteredEvents[] = "events"; 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct EventRouter::ListenerProcess { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerProcess(content::RenderProcessHost* process, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : process(process), extension_id(extension_id) {} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator<(const ListenerProcess& that) const { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process < that.process) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process == that.process && extension_id < that.extension_id) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* browser_context_id, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* event_args, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UserGestureState user_gesture, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EventFilteringInfo& info) { 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyApiEventDispatched(browser_context_id, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_name, 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) make_scoped_ptr(event_args->DeepCopy())); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue args; 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args.Set(0, new base::StringValue(event_name)); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Set(1, event_args); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Set(2, info.AsValue().release()); 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ipc_sender->Send(new ExtensionMsg_MessageInvoke( 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MSG_ROUTING_CONTROL, 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_id, 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) kEventBindings, 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "dispatchEvent", 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) args, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_gesture == USER_GESTURE_ENABLED)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DispatchExtensionMessage does _not_ take ownership of event_args, so we 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must ensure that the destruction of args does not attempt to free it. 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> removed_event_args; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Remove(1, &removed_event_args); 1303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ignore_result(removed_event_args.release()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 134effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochEventRouter* EventRouter::Get(content::BrowserContext* browser_context) { 135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return ExtensionSystem::Get(browser_context)->event_router(); 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string EventRouter::GetBaseEventName(const std::string& full_event_name) { 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t slash_sep = full_event_name.find('/'); 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return full_event_name.substr(0, slash_sep); 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* browser_context_id, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ListValue> event_args, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UserGestureState user_gesture, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EventFilteringInfo& info) { 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DispatchExtensionMessage(ipc_sender, 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_id, 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_id, 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_name, 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_args.get(), 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) user_gesture, 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info); 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserThread::PostTask( 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserThread::UI, 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&EventRouter::IncrementInFlightEventsOnUI, 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_id, 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_id)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)EventRouter::EventRouter(BrowserContext* browser_context, 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionPrefs* extension_prefs) 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : browser_context_(browser_context), 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_(extension_prefs), 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_(this), 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) listeners_(this) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch registrar_.Add(this, 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_ENABLED, 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(browser_context_)); 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventRouter::~EventRouter() {} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::AddEventListener(const std::string& event_name, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.AddListener(EventListener::ForExtension( 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, extension_id, process, scoped_ptr<DictionaryValue>())); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::RemoveEventListener(const std::string& event_name, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<EventListener> listener = EventListener::ForExtension( 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, extension_id, process, scoped_ptr<DictionaryValue>()); 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.RemoveListener(listener.get()); 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EventRouter::AddEventListenerForURL(const std::string& event_name, 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RenderProcessHost* process, 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url) { 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.AddListener(EventListener::ForURL( 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, listener_url, process, scoped_ptr<DictionaryValue>())); 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EventRouter::RemoveEventListenerForURL(const std::string& event_name, 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RenderProcessHost* process, 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url) { 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<EventListener> listener = EventListener::ForURL( 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, listener_url, process, scoped_ptr<DictionaryValue>()); 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.RemoveListener(listener.get()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::RegisterObserver(Observer* observer, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name) { 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Observing sub-event names like "foo.onBar/123" is not allowed. 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(event_name.find('/') == std::string::npos); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_[event_name] = observer; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::UnregisterObserver(Observer* observer) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ObserverMap::iterator> iters_to_remove; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ObserverMap::iterator iter = observers_.begin(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != observers_.end(); ++iter) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter->second == observer) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iters_to_remove.push_back(iter); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < iters_to_remove.size(); ++i) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.erase(iters_to_remove[i]); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::OnListenerAdded(const EventListener* listener) { 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const EventListenerInfo details(listener->event_name(), 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) listener->extension_id(), 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener->listener_url(), 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) listener->GetBrowserContext()); 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string base_event_name = GetBaseEventName(listener->event_name()); 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ObserverMap::iterator observer = observers_.find(base_event_name); 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (observer != observers_.end()) { 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed. 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tracked_objects::ScopedProfile tracking_profile( 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE_WITH_EXPLICIT_FUNCTION( 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "EventRouter_OnListenerAdded_ObserverCall")); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer->second->OnListenerAdded(details); 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::OnListenerRemoved(const EventListener* listener) { 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const EventListenerInfo details(listener->event_name(), 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) listener->extension_id(), 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener->listener_url(), 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) listener->GetBrowserContext()); 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string base_event_name = GetBaseEventName(listener->event_name()); 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ObserverMap::iterator observer = observers_.find(base_event_name); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer != observers_.end()) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer->second->OnListenerRemoved(details); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::AddLazyEventListener(const std::string& event_name, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool is_new = listeners_.AddListener(EventListener::ForExtension( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name, extension_id, NULL, scoped_ptr<DictionaryValue>())); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_new) { 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<std::string> events = GetRegisteredEvents(extension_id); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool prefs_is_new = events.insert(event_name).second; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs_is_new) 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRegisteredEvents(extension_id, events); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::RemoveLazyEventListener(const std::string& event_name, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<EventListener> listener = EventListener::ForExtension( 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, extension_id, NULL, scoped_ptr<DictionaryValue>()); 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool did_exist = listeners_.RemoveListener(listener.get()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (did_exist) { 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<std::string> events = GetRegisteredEvents(extension_id); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool prefs_did_exist = events.erase(event_name) > 0; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(prefs_did_exist); 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRegisteredEvents(extension_id, events); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::AddFilteredEventListener(const std::string& event_name, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue& filter, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool add_lazy_listener) { 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.AddListener(EventListener::ForExtension( 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id, 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) process, 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<DictionaryValue>(filter.DeepCopy()))); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (add_lazy_listener) { 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool added = listeners_.AddListener(EventListener::ForExtension( 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id, 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL, 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<DictionaryValue>(filter.DeepCopy()))); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (added) 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AddFilterToEvent(event_name, extension_id, &filter); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::RemoveFilteredEventListener( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue& filter, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool remove_lazy_listener) { 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<EventListener> listener = EventListener::ForExtension( 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_name, 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id, 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) process, 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<DictionaryValue>(filter.DeepCopy())); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.RemoveListener(listener.get()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remove_lazy_listener) { 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener->MakeLazy(); 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool removed = listeners_.RemoveListener(listener.get()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (removed) 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RemoveFilterFromEvent(event_name, extension_id, &filter); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventRouter::HasEventListener(const std::string& event_name) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return listeners_.HasListenerForEvent(event_name); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return listeners_.HasListenerForExtension(extension_id, event_name); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventRouter::HasEventListenerImpl(const ListenerMap& listener_map, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::const_iterator it = listener_map.find(event_name); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == listener_map.end()) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::set<ListenerProcess>& listeners = it->second; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id.empty()) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !listeners.empty(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener != listeners.end(); ++listener) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listener->extension_id == extension_id) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::set<std::string> EventRouter::GetRegisteredEvents( 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id) { 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<std::string> events; 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ListValue* events_value = NULL; 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!extension_prefs_ || 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !extension_prefs_->ReadPrefAsList( 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_id, kRegisteredEvents, &events_value)) { 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return events; 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < events_value->GetSize(); ++i) { 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string event; 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (events_value->GetString(i, &event)) 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) events.insert(event); 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return events; 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void EventRouter::SetRegisteredEvents(const std::string& extension_id, 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::set<std::string>& events) { 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ListValue* events_value = new ListValue; 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (std::set<std::string>::const_iterator iter = events.begin(); 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) iter != events.end(); ++iter) { 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) events_value->Append(new base::StringValue(*iter)); 38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_->UpdateExtensionPref( 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_id, kRegisteredEvents, events_value); 39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void EventRouter::AddFilterToEvent(const std::string& event_name, 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id, 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DictionaryValue* filter) { 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionPrefs::ScopedDictionaryUpdate update( 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_, extension_id, kFilteredEvents); 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DictionaryValue* filtered_events = update.Get(); 39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!filtered_events) 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) filtered_events = update.Create(); 40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ListValue* filter_list = NULL; 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!filtered_events->GetList(event_name, &filter_list)) { 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) filter_list = new ListValue; 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) filtered_events->SetWithoutPathExpansion(event_name, filter_list); 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) filter_list->Append(filter->DeepCopy()); 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void EventRouter::RemoveFilterFromEvent(const std::string& event_name, 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id, 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DictionaryValue* filter) { 41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionPrefs::ScopedDictionaryUpdate update( 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_, extension_id, kFilteredEvents); 41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DictionaryValue* filtered_events = update.Get(); 41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ListValue* filter_list = NULL; 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!filtered_events || 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < filter_list->GetSize(); i++) { 42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DictionaryValue* filter = NULL; 42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(filter_list->GetDictionary(i, &filter)); 42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (filter->Equals(filter)) { 42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) filter_list->Remove(i, NULL); 42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const DictionaryValue* EventRouter::GetFilteredEvents( 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id) { 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DictionaryValue* events = NULL; 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_->ReadPrefAsDictionary( 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_id, kFilteredEvents, &events); 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return events; 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void EventRouter::BroadcastEvent(scoped_ptr<Event> event) { 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DispatchEventImpl(std::string(), linked_ptr<Event>(event.release())); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchEventToExtension(const std::string& extension_id, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Event> event) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!extension_id.empty()); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DispatchEventImpl(extension_id, linked_ptr<Event>(event.release())); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid EventRouter::DispatchEventWithLazyListener(const std::string& extension_id, 451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<Event> event) { 452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!extension_id.empty()); 453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::string event_name = event->event_name; 454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool has_listener = ExtensionHasEventListener(extension_id, event_name); 455ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!has_listener) 456ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch AddLazyEventListener(event_name, extension_id); 457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DispatchEventToExtension(extension_id, event.Pass()); 458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!has_listener) 459ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RemoveLazyEventListener(event_name, extension_id); 460ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 461ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event) { 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We don't expect to get events from a completely different browser context. 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!event->restrict_to_browser_context || 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionsBrowserClient::Get()->IsSameContext( 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_, event->restrict_to_browser_context)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<const EventListener*> listeners( 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.GetEventListeners(*event)); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventDispatchIdentifier> already_dispatched; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We dispatch events for lazy background pages first because attempting to do 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so will cause those that are being suspended to cancel that suspension. 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As canceling a suspension entails sending an event to the affected 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // background page, and as that event needs to be delivered before we dispatch 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event we are dispatching here, we dispatch to the lazy listeners here 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first. 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<const EventListener*>::iterator it = listeners.begin(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); it++) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EventListener* listener = *it; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restrict_to_extension_id.empty() || 484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) restrict_to_extension_id == listener->extension_id()) { 485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (listener->IsLazy()) { 486010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DispatchLazyEvent(listener->extension_id(), event, &already_dispatched); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<const EventListener*>::iterator it = listeners.begin(); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners.end(); it++) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EventListener* listener = *it; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restrict_to_extension_id.empty() || 495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) restrict_to_extension_id == listener->extension_id()) { 496010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (listener->process()) { 497010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), 498010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) listener->extension_id()); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ContainsKey(already_dispatched, dispatch_id)) { 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DispatchEventToProcess(listener->extension_id(), 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener->listener_url(), 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener->process(), 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchLazyEvent( 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event, 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventDispatchIdentifier>* already_dispatched) { 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Check both the original and the incognito browser context to see if we 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should load a lazy bg page to handle the event. The latter case 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs in the case of split-mode extensions. 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id); 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!extension) 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (MaybeLoadLazyBackgroundPageToDispatchEvent( 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_, extension, event)) { 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) already_dispatched->insert(std::make_pair(browser_context_, extension_id)); 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (browser_client->HasOffTheRecordContext(browser_context_) && 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IncognitoInfo::IsSplitMode(extension)) { 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* incognito_context = 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_client->GetOffTheRecordContext(browser_context_); 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (MaybeLoadLazyBackgroundPageToDispatchEvent( 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) incognito_context, extension, event)) { 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) already_dispatched->insert( 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::make_pair(incognito_context, extension_id)); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchEventToProcess(const std::string& extension_id, 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event) { 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserContext* listener_context = process->GetBrowserContext(); 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProcessMap* process_map = ProcessMap::Get(listener_context); 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(kalman): Convert this method to use 5496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // ProcessMap::GetMostLikelyContextType. 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = 5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( 5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id); 5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // NOTE: |extension| being NULL does not necessarily imply that this event 5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // shouldn't be dispatched. Events can be dispatched to WebUI as well. 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!extension && !extension_id.empty()) { 5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Trying to dispatch an event to an extension that doesn't exist. The 5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // extension could have been removed, but we do not unregister it until the 5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // extension process is unloaded. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension) { 5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Dispatching event to an extension. 5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the event is privileged, only send to extension processes. Otherwise, 5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // it's OK to send to normal renderers (e.g., for content scripts). 5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!process_map->Contains(extension->id(), process->GetID()) && 5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !ExtensionAPI::GetSharedInstance()->IsAvailableInUntrustedContext( 5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->event_name, extension)) { 5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the event is restricted to a URL, only dispatch if the extension has 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // permission for it (or if the event originated from itself). 5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!event->event_url.is_empty() && 5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->event_url.host() != extension->id() && 5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !extension->permissions_data() 5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->active_permissions() 5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->HasEffectiveAccessToURL(event->event_url)) { 5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!CanDispatchEventToBrowserContext(listener_context, extension, event)) { 5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (content::ChildProcessSecurityPolicy::GetInstance() 5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->HasWebUIBindings(process->GetID())) { 5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Dispatching event to WebUI. 5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ExtensionAPI::GetSharedInstance()->IsAvailableToWebUI( 5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->event_name, listener_url)) { 5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Dispatching event to a webpage - however, all such events (e.g. 5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // messaging) don't go through EventRouter so this should be impossible. 5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!event->will_dispatch_callback.is_null()) { 6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->will_dispatch_callback.Run( 6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener_context, extension, event->event_args.get()); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DispatchExtensionMessage(process, 6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener_context, 6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id, 6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->event_name, 6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->event_args.get(), 6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->user_gesture, 6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->filter_info); 6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension) 6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IncrementInFlightEvents(listener_context, extension); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool EventRouter::CanDispatchEventToBrowserContext( 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* context, 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension, 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const linked_ptr<Event>& event) { 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Is this event from a different browser context than the renderer (ie, an 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // incognito tab event sent to a normal process, or vice versa). 624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool cross_incognito = event->restrict_to_browser_context && 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) context != event->restrict_to_browser_context; 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!cross_incognito) 627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ExtensionsBrowserClient::Get()->CanExtensionCrossIncognito( 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension, context); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( 633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* context, 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event) { 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CanDispatchEventToBrowserContext(context, extension, event)) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LazyBackgroundTaskQueue* queue = ExtensionSystem::Get( 640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) context)->lazy_background_task_queue(); 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (queue->ShouldEnqueueTask(context, extension)) { 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) linked_ptr<Event> dispatched_event(event); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there's a dispatch callback, call it now (rather than dispatch time) 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to avoid lifetime issues. Use a separate copy of the event args, so they 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // last until the event is dispatched. 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!event->will_dispatch_callback.is_null()) { 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dispatched_event.reset(event->DeepCopy()); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dispatched_event->will_dispatch_callback.Run( 650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) context, extension, dispatched_event->event_args.get()); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure we don't call it again at dispatch time. 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dispatched_event->will_dispatch_callback.Reset(); 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) queue->AddPendingTask(context, extension->id(), 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EventRouter::DispatchPendingEvent, 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), dispatched_event)); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 66590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void EventRouter::IncrementInFlightEventsOnUI( 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* browser_context_id, 66790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id) { 668effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* browser_context = 670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reinterpret_cast<BrowserContext*>(browser_context_id); 671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) 6727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 6730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter* event_router = EventRouter::Get(browser_context); 67490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!event_router) 67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const Extension* extension = 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID( 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id); 67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!extension) 68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_router->IncrementInFlightEvents(browser_context, extension); 68290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 68390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void EventRouter::IncrementInFlightEvents(BrowserContext* context, 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only increment in-flight events if the lazy background page is active, 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because that's the only time we'll get an ACK. 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (BackgroundInfo::HasLazyBackgroundPage(extension)) { 6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessManager* pm = ExtensionSystem::Get(context)->process_manager(); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = pm->GetBackgroundHostForExtension(extension->id()); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pm->IncrementLazyKeepaliveCount(extension); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void EventRouter::OnEventAck(BrowserContext* context, 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessManager* pm = ExtensionSystem::Get(context)->process_manager(); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = pm->GetBackgroundHostForExtension(extension_id); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event ACK is routed to the background host, so this should never be 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULL. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(host); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): We should never get this message unless 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // HasLazyBackgroundPage is true. Find out why we're getting it anyway. 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (host->extension() && 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BackgroundInfo::HasLazyBackgroundPage(host->extension())) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pm->DecrementLazyKeepaliveCount(host->extension()); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!host) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listeners_.HasProcessListener(host->render_process_host(), 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->extension()->id())) { 7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // URL events cannot be lazy therefore can't be pending, hence the GURL(). 7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DispatchEventToProcess( 7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) host->extension()->id(), GURL(), host->render_process_host(), event); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventRouter::Observe(int type, 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* renderer = 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<content::RenderProcessHost>(source).ptr(); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove all event listeners associated with this renderer. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.RemoveListenersForProcess(renderer); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_ENABLED: { 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the extension has a lazy background page, make sure it gets loaded 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to register the events the extension is interested in. 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<const Extension>(details).ptr(); 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (BackgroundInfo::HasLazyBackgroundPage(extension)) { 7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LazyBackgroundTaskQueue* queue = ExtensionSystem::Get( 742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_)->lazy_background_task_queue(); 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) queue->AddPendingTask(browser_context_, extension->id(), 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DoNothing)); 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, 7545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension) { 7555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Add all registered lazy listeners to our cache. 7565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::set<std::string> registered_events = 7575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetRegisteredEvents(extension->id()); 7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); 7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); 7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (filtered_events) 7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); 7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, 7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension, 7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnloadedExtensionInfo::Reason reason) { 7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Remove all registered lazy listeners from our cache. 7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listeners_.RemoveLazyListenersForExtension(extension->id()); 7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Event::Event(const std::string& event_name, 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> event_args) 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : event_name(event_name), 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_args(event_args.Pass()), 775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) restrict_to_browser_context(NULL), 7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user_gesture(EventRouter::USER_GESTURE_UNKNOWN) { 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(this->event_args.get()); 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event::Event(const std::string& event_name, 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> event_args, 782f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* restrict_to_browser_context) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_name(event_name), 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_args(event_args.Pass()), 785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) restrict_to_browser_context(restrict_to_browser_context), 7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) user_gesture(EventRouter::USER_GESTURE_UNKNOWN) { 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(this->event_args.get()); 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Event::Event(const std::string& event_name, 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ListValue> event_args, 792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* restrict_to_browser_context, 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& event_url, 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventRouter::UserGestureState user_gesture, 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EventFilteringInfo& filter_info) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_name(event_name), 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_args(event_args.Pass()), 798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) restrict_to_browser_context(restrict_to_browser_context), 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_url(event_url), 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_gesture(user_gesture), 8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) filter_info(filter_info) { 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(this->event_args.get()); 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Event::~Event() {} 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Event* Event::DeepCopy() { 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Event* copy = new Event(event_name, 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue>(event_args->DeepCopy()), 810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) restrict_to_browser_context, 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event_url, 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_gesture, 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filter_info); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) copy->will_dispatch_callback = will_dispatch_callback; 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return copy; 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EventListenerInfo::EventListenerInfo(const std::string& event_name, 819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& extension_id, 8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url, 821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* browser_context) 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : event_name(event_name), 823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_id(extension_id), 8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) listener_url(listener_url), 8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser_context(browser_context) { 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 829